これを実装する前に、これが未定義の動作や競合状態につながるかどうかを確認したいと思います。
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);
}
私の計画は、これらの信号をスロットにフェッチして、このブロックがアップロードされたことに注意する必要があり (ブロック リストを配置してこのブロブをファイナライズできるようにリストに配置します)、インデックスを 1 つ増やします (これは 5 から始まります)。 ) データの新しいチャンクを取得し、プロセス全体をやり直します。
私の問題は、そのうちの 2 つがまったく同時に終了した場合はどうなるかということです。ここではスレッドを扱っていませんが、HTTP 要求はデフォルトでスレッド化されているため、ここではどうなるのでしょうか? シグナルはキューに入れられていますか (または QueuedConnection を使用する必要がありますか)? スロットを並行して呼び出すことはできますか? これを行うより良い方法はありますか?