tbb实现了线程安全的queue,这样程序员既可以不用和那些lock,mutex,criticalsection打交道,又大大提高性能,太给力了。。比较的结果见代码中的注释。结果可以看出代码足足少一半,性能足足生一倍,诱人!
#include <Windows.h> #include <deque> #include <iostream> #include <process.h> #include <tbbconcurrent_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, 11656 2. not tbb, is criticalsection, not mutex, 8172 3. 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; } #else void 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 #endif void main(){ InitializeCriticalSection(&s_cs); _beginthread(thread2_, 0, NULL); _beginthread(thread2_, 0, NULL);//2 consumer _beginthread(thread1_, 0, NULL); while(s_running){ Sleep(10); } }