tbb 线程安全concurrent_queue的性能
tbb实现了线程安全的queue,这样程序员既可以不用和那些lock,mutex,criticalsection打交道,又大大提高性能,太给力了。。比较的结果见代码中的注释。结果可以看出代码足足少一半,性能足足生一倍,诱人!
#include <Windows.h>#include <deque>#include <iostream>#include <process.h>#include <tbb\concurrent_queue.h>using namespace std;static CRITICAL_SECTION s_cs;static HANDLE s_mutex = CreateMutex(NULL, FALSE, NULL);static deque<int> s_queue;const static int LOOP_COUNT_ = 3000000;static bool s_running = true;static tbb::concurrent_queue<int> s_tbb_queue;/*1. not tbb, not criticalsection, is mutex, 116562. not tbb, is criticalsection, not mutex, 81723. is tbb, not criticalsection, not mutex, 3828*//*下面的两个宏是开关*/#define _MUTEX_TEST_ ""#define _USE_TBB_""#ifdef _USE_TBB_void thread1_(void* dummy){LONGLONG start = GetTickCount();for (int i = 0; i < LOOP_COUNT_; i ++){s_tbb_queue.push(i);}cout << GetTickCount() - start << endl;Sleep(20000);s_running = false;}void thread2_(void* dummy){int i = 0;int k;while (s_running){if (s_tbb_queue.try_pop(k)){i ++;} else{Sleep(1);}}cout << "consume " << i << endl;}#else#ifdef _MUTEX_TEST_void thread1_(void* dummy){LONGLONG start = GetTickCount();for (int i = 0; i < LOOP_COUNT_; i ++){WaitForSingleObject(s_mutex, INFINITE);s_queue.push_back(i);ReleaseMutex(s_mutex);}cout << GetTickCount() - start << endl;Sleep(20000);s_running = false;}void thread2_(void* dummy){int i = 0;while (s_running){WaitForSingleObject(s_mutex, INFINITE);bool bEmpty = s_queue.empty();if (!bEmpty){int res = s_queue.front();s_queue.pop_front();}ReleaseMutex(s_mutex);if (!bEmpty){i ++;} else {Sleep(1);}}cout << "consume " << i << endl;}#elsevoid thread1_(void* dummy){LONGLONG start = GetTickCount();for (int i = 0; i < LOOP_COUNT_; i ++){EnterCriticalSection(&s_cs);s_queue.push_back(i);LeaveCriticalSection(&s_cs);}cout << GetTickCount() - start << endl;Sleep(20000);s_running = false;}void thread2_(void* dummy){int i = 0;while (s_running){EnterCriticalSection(&s_cs);bool bEmpty = s_queue.empty();if (!bEmpty){int res = s_queue.front();s_queue.pop_front();}LeaveCriticalSection(&s_cs);if (!bEmpty){i ++;} else {Sleep(1);}}cout << "consume " << i << endl;}#endif#endifvoid main(){InitializeCriticalSection(&s_cs);_beginthread(thread2_, 0, NULL);_beginthread(thread2_, 0, NULL);//2 consumer_beginthread(thread1_, 0, NULL);while(s_running){Sleep(10);}}