#include <iostream>
#include <chrono>
#include <vector>
#include <future>
#include <boost/lockfree/queue.hpp>
#include <boost/circular_buffer.hpp>
using namespace std::chrono;
const int queue_capacity = 1000;
const int producer_num = 4;
const int max_count = 10000;
template<typename Func>
system_clock::duration measure(Func f) {
auto start = system_clock::now();
f();
return system_clock::now() - start;
}
void test_cb() {
boost::circular_buffer<int> cb(queue_capacity);
std::mutex cb_mu;
std::thread consumer([&] {
std::atomic_int consume_count(0);
while (consume_count < max_count) {
std::lock_guard<std::mutex> lock(cb_mu);
if (!cb.empty()) {
int task = cb.front();
cb.pop_front();
++consume_count;
}
}
});
std::vector<std::thread> producers;
std::atomic_int producer_count(0);
for (int i = 0; i < producer_num; ++i) {
producers.emplace_back([&] {
while (producer_count < max_count) {
std::lock_guard<std::mutex> lock(cb_mu);
if (!cb.full()) {
cb.push_back(1);
++producer_count;
}
}
});
}
consumer.join();
for (int i = 0; i < producers.size(); ++i) {
producers[i].join();
}
}
void test_lockfree() {
boost::lockfree::queue<int, boost::lockfree::capacity<queue_capacity>> lockfree_queue;
std::thread consumer([&] {
std::atomic_int consume_count(0);
while (consume_count < max_count) {
if (!lockfree_queue.empty()) {
int task;
if(lockfree_queue.pop(task))
++consume_count;
}
}
});
std::vector<std::thread> producers;
std::atomic_int producer_count(0);
for (int i = 0; i < producer_num; ++i) {
producers.emplace_back([&] {
while (producer_count < max_count) {
if(lockfree_queue.push(1))
++producer_count;
}
});
}
consumer.join();
for (int i = 0; i < producers.size(); ++i) {
producers[i].join();
}
}
int main() {
std::cout << "test_cb cost: " << duration_cast<milliseconds>(measure(test_cb)).count() << "ms" << std::endl;
std::cout << "test_lockfree cost: " << duration_cast<milliseconds>(measure(test_lockfree)).count() << "ms" << std::endl;
return 0;
}