Как обрабатывать многопоточную очередь

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

Что я здесь не так делаю?

РЕДАКТИРОВАТЬ

Видимо я неправильно прочитал ссылку выше. Имеется ли реализация потока, ориентированная на многопотоковое исполнение, которая делает то, что я пытаюсь сделать? Я знаю, что это общая стратегия организации потоков.

2

Решение

Как указано в комментариях, контейнеры STL не являются поточно-ориентированными для операций чтения-записи. Вместо этого попробуйте concurrent_queue класс от TBB или же PPL, например.:

void doWork(concurrent_queue<string>& itemQueue) {
string result;
while(itemQueue.try_pop(result)) {
// you have `result`
}
}
4

Другие решения

Я закончил реализацию BlockingQueueс предложенным исправлением pop, Вот:

Создание очереди блокировки

2

Контейнеры C ++ определенно не являются потокобезопасными BlockingCollection является потокобезопасным коллекционным классом C ++ 11, который моделируется после класса .NET BlockingCollection. Он оборачивает std :: deque, чтобы обеспечить одновременное добавление и получение элементов из нескольких потоков в очередь. А также стековые и приоритетные контейнеры.

0