これを実装する前に、これが未定義の動作または競合状態につながるかどうか確認したいと思います。信号とスロットを使用したファイルのインクリメンタルアップロード
ファイルをアップロードするときは、ブロック単位で行う必要があります。私は並行して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);
}
uploaderのputBlock関数では、呼び出したQNetworkAccessManagerを呼び出します。それが完了したら、ブロックされたブロックのどれかがわかるように、失敗したか、succededか、取り消されたか、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);
}
私の計画は今率を高める、このブロックは(このブロブを完成させるためにブロックリストを置くことができるように、リストに入れて)アップロードされたことにご注意くださいスロットにこれらの信号を取り出すことです
(5から始まります)、新しいデータチャンクを取り出して、プロセス全体をやり直します。
私の問題は、そのうち2つが同時に正確に終了するとどうなりますか?私はここでスレッドを扱っていませんが、HTTPリクエストはデフォルトでスレッドされているので、ここでは何がありますか?シグナルはキューに入れられていますか(またはQueuedConnectionを使用すべきですか)?スロットを並行して呼び出すことはできますか?これを行うより良い方法はありますか?
このスロットには別のスレッドがアクセスすることはありません。これは、qt/C++のシグナル/スロットメカニズムでどのように動作するのかを知る必要があります。 – chikuba