2012-04-19 40 views
0

在执行此操作之前,我想检查这是否会导致未定义的行为或竞争条件。使用信号和插槽增量上传文件

当上传文件到asure时,这必须以块为单位完成。我想要并行上传5个块,并且他们都从同一个文件中获取数据。这将会发生这样的情况:

char *currentDataChunk; 
int currentDataChunkSize; 

connect(_blobStorageProvider, SIGNAL(putBlockSucceded(int)), this, SLOT(finalizeAndUploadNextBlock(int))); 

int parallelUploads = ((_item->size()/MAX_BLOCK_SIZE) >= MAX_PARALLEL_BLOCKUPLOADS) ? MAX_PARALLEL_BLOCKUPLOADS : (_item->size()/MAX_BLOCK_SIZE); 

_latestProcessedBlockId = (parallelUploads - 1); 

for(int i = 0; i < parallelUploads; i++) { 

    currentDataChunkSize = _item->read(currentDataChunk, MAX_BLOCK_SIZE); 

    ... 

    uploader->putBlock(_container, _blobName, currentDataChunk, i); 
} 

在上传器中的putBlock函数中,它调用了QNetworkAccessManager。完成后,如果失败,成功或取消,则会发回一个信号,以及blockId,以便我知道已上传哪个块。

void BigBlobUploader::finalizeAndUploadNextBlock(int blockId) { 

    // FINALIZE BY ADDING SUCCESSFUL BLOCK TO FUTURE BLOCKLIST 
    QByteArray temp; 

    for(int i = 0; i != sizeof(blockId); i++) { 
     temp.append((char)(blockId >> (i * 8))); 
    } 

    _uploadedBlockIds.insert(blockId, QString(temp.toBase64())); 
    this->uploadNextBlock(); 
} 

void BigBlobUploader::uploadNextBlock() { 

    char *newDataChunk; 
    int newDataChunkSize = _item->read(newDataChunk, MAX_BLOCK_SIZE); 
    ... 
    _latestProcessedBlockId++; 
    uploader->putBlock(_container, _blobName, newDataChunk, _latestProcessedBlockId); 
} 

我现在的计划是获取这些信号的插槽应该注意到,该块被上传(把它放在一个列表,以便能够把块列表来完成此Blob),增加索引通过一个(从5开始)并获取新的数据块并重做整个过程。

现在我的问题是,如果他们中的两个在同一时间完成了怎么办?我没有在这里处理线程,但由于HTTP请求默认是线程化的,这里是什么情况?信号是排队的(还是应该使用QueuedConnection)?一个插槽可以并行调用吗?有没有更好的方法来做到这一点?

回答

-1

我对QNetworkAccessManager并不熟悉。但一般来说,要处理竞争条件,请使用锁。通常,在C#中使用锁的方式是利用lock关键字。喜欢的东西:

private object lockingObject = new object(); 

In a method: 

lock 
{ 
       // If a thread acquires a lock, another thread is blocked here until the lock is released. 
} 

此外,你可以参考http://msdn.microsoft.com/en-us/library/c5kehkcz(v=vs.100).aspx以获取更多信息。

最好的问候,

Ming Xu。

+0

事情是,我不会有不同的线程访问此插槽,我需要知道这将如何与信号/槽机制在qt/c + +,而不是c# – chikuba 2012-04-19 09:03:24

0

对不便,我认为您使用.NET,因为您已将Windows Azure标记添加到此线程。我很喜欢Windows Azure,但是我对Qt的理解是有限的。但是,在其他并发场景中使用信号/插槽不会有所不同。本文档可能有帮助:http://qt-project.org/doc/qt-4.8/signalsandslots.html

最好的问候,

Ming Xu。