2014-05-13 110 views
1

C++容器是supposed to be thread-safe by default。我必须用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

C++容器不是线程的安全默认。从链接到的页面引用:“使任何迭代器无效的容器操作都会修改容器,并且无法与现有迭代器上的任何操作同时执行,即使这些迭代器未失效。” –

+1

*默认情况下,C++容器应该是线程安全的* - 什么给了你这个想法?当你有多个线程调用'const'成员函数时,它们只是线程安全的,而不是在一个或多个线程正在修改容器时。 – Praetorian

+0

这可能是一个措辞问题:容器的方法被认为是线程安全的,但在它们上运行的迭代器不是。 – didierc

回答

4

正如注释中所指出的,STL容器对于读写操作而言不是线程安全的。相反,尝试从TBBPPLconcurrent_queue类如:

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

另一个会是一个blockingQueue:http://stackoverflow.com/questions/12805041/c-equivalent-to-javas-blockingqueue – tofi9