#ifndef _MSG_QUEUE_H
#define _MSG_QUEUE_H
#include <mutex>
#include <condition_variable>
#include <list>
template<typename T>
class MsgQueue
{
public:
MsgQueue() {};
T* pop(void) {
T* r = nullptr;
std::unique_lock<std::mutex> lk(mtx);
m_cv.wait(lk, [&] {return !m_list.empty(); });
r = m_list.front();
m_list.pop_front();
return r;
}
T* pop_wait_ms(uint32_t ms) {
T* r = nullptr;
if (0 == ms) {
return pop();
}
auto t = std::chrono::milliseconds(ms);
std::unique_lock<std::mutex> lk(mtx);
m_cv.wait_for(lk,t, [&] {return !m_list.empty(); });
if (!m_list.empty()) {
r = m_list.front();
m_list.pop_front();
}
return r;
}
void push(T* v) {
std::unique_lock<std::mutex> lk(mtx);
m_cv.wait(lk, [&] {return m_list.size()<max_msg; });
m_list.push_back(v);
}
private:
std::list<T*> m_list;
std::mutex mtx;
std::condition_variable m_cv;
unsigned int max_msg = 10;
};
#endif // !_MSG_QUEUE_H
使用
void msg_q_test()
{
printf("%ld\n", GetCurrentProcessId());
MsgQueue<string> q1;
auto f = [&](int x) {
if (x) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout <<x<<":" << std::this_thread::get_id() << std::endl;
while (1) {
std::cout << *q1.pop();
}
};
auto f2 = [&](int x) {
if (x) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << x << ":" << std::this_thread::get_id() << std::endl;
while (1) {
auto p = q1.pop_wait_ms(5000);
if(p)
std::cout << *p << std::endl;
std::cout << "wait timeout\n";
break;
}
};
std::thread t1(f,0), t2(f2,1);
t1.join();
t2.join();
}