3

C++ コンテナーは、デフォルトでスレッドセーフであると想定されていますqueueこのコードの場合:

#include <thread>
using std::thread;
#include <iostream>
using std::cout;
using std::endl;
#include <queue>
using std::queue;
#include <string>
using std::string;
using std::to_string;
#include <functional>
using std::ref;


void fillWorkQueue(queue<string>& itemQueue) {
    int size = 40000;
    for(int i = 0; i < size; i++)
        itemQueue.push(to_string(i));
}

void doWork(queue<string>& itemQueue) {
    while(!itemQueue.empty()) {
        itemQueue.pop();
    }   
}

void singleThreaded() {
    queue<string> itemQueue;
    fillWorkQueue(itemQueue);
    doWork(itemQueue);
    cout << "done\n";
}

void multiThreaded() {
    queue<string> itemQueue;
    fillWorkQueue(itemQueue);
    thread t1(doWork, ref(itemQueue));
    thread t2(doWork, ref(itemQueue));
    t1.join();
    t2.join();
    cout << "done\n";
}

int main() {
    cout << endl;

    // Single Threaded
    cout << "singleThreaded\n";
    singleThreaded();
    cout << endl;

    // Multi Threaded
    cout << "multiThreaded\n";
    multiThreaded();
    cout << endl;
}

私は得ています:

singleThreaded
done

multiThreaded
main(32429,0x10e530000) malloc: *** error for object 0x7fe4e3883e00: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
make: *** [run] Abort trap: 6

ここで何が間違っていますか?

編集

上のリンクを読み間違えたようです。私がやろうとしていることを実行できるスレッドセーフなキューの実装はありますか? これが一般的なスレッド編成戦略であることは知っています。

4

3 に答える 3

5

コメントで指摘されているように、STL コンテナーは読み取り/書き込み操作に対してスレッドセーフではありません。代わりに、TBBまたはPPLconcurrent_queueのクラスを試してください。

void doWork(concurrent_queue<string>& itemQueue) {
    string result;
    while(itemQueue.try_pop(result)) {
        // you have `result`
    }   
}
于 2014-05-14T01:11:07.600 に答える
2

BlockingQueue私はここに提案された修正で、を実装することになりpopました:

ブロッキング キューの作成

于 2014-05-14T18:24:31.617 に答える
0

C++ コンテナーは確実にスレッドセーフではありません。BlockingCollectionは、.NET BlockingCollection クラスをモデルにした C++11 スレッド セーフ コレクション クラスです。std::deque をラップして、複数のスレッドからキューへの項目の同時追加および取得を提供します。スタックおよび優先コンテナーと同様に。

于 2018-10-08T11:04:55.080 に答える