参考:
- https://oneapi-src.github.io/oneTBB/main/tbb_userguide/Concurrent_Queue_Classes.html
- https://cloud.tencent.com/developer/ask/sof/767428
- http://selkie.macalester.edu/csinparallel/modules/DrugDesignInParallel/build/html/c++11threads/c++11threads.html
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <tbb/concurrent_queue.h>
#include <assert.h>
#include "../util/thread_pool.h"
ThreadPool worker_pool(1);
tbb::concurrent_bounded_queue<int> tbb_queue;
// tbb::concurrent_queue<int> tbb_queue;
std::queue<int> std_queue;
std::mutex queue_mux_;
/*----------------------------------TBB---------------------------------------*/
void tbb_f(int data) {
// std::cout << " f : data " << data << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(20)); // 模拟延迟
tbb_queue.push(data);
}
void test_tbb() {
tbb_queue.set_capacity(2);
tbb_queue.push(1);
tbb_queue.push(2);
int data;
tbb_queue.pop(data);
for (int i = 0; i < 1000; i++) {
// std::cout << "i=" << i << " deal with: data " << data << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(20)); // 模拟延迟
worker_pool.enqueue(tbb_f, data);
tbb_queue.pop(data);
}
}
/*----------------------------------------------------------------------------*/
static void Sleep(double t) {
timespec req;
req.tv_sec = (int) t;
req.tv_nsec = (int64_t)(1e9 * (t - (int64_t) t));
nanosleep(&req, NULL);
}
int get_data() {
// Sleep(1.00001);
while (true) {
if (!std_queue.empty()) {
std::unique_lock<std::mutex> lk(queue_mux_);
auto data = std_queue.front();
std_queue.pop();
return data;
}
Sleep(0.0000001);
}
}
void recycle_data(int data) {
{
std::unique_lock<std::mutex> lk(queue_mux_);
std_queue.push(data);
}
}
void std_f(int data) {
// std::cout << " f : data " << data << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(20)); // 模拟延迟
recycle_data(data);
}
void test_std() {
std_queue.push(1);
std_queue.push(2);
int data = get_data();
for (int i = 0; i < 1000; i++) {
// std::cout << "i=" << i << " deal with: data " << data << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(20)); // 模拟延迟
worker_pool.enqueue(std_f, data);
data = get_data();
}
}
int main() {
// cmd: g++ test_concurrent_queue.cpp -lpthread -ltbb && ./a.out
{
double insert_time = clock();
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
test_tbb();
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
std::cout << " test_tbb time: "
<< time_span.count()
<< " sec" << std::endl;
}
{
double insert_time = clock();
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
test_std();
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
std::cout << " test_std time: "
<< time_span.count()
<< " sec" << std::endl;
}
return 0;
}
/*
output:
test_tbb time: 20.086 sec
test_std time: 20.0813 sec
~ThreadPool
*/