C++11 消费者线程与生产者线程demo
#include <stdio.h>
#include <thread>
#include <memory>
#include <list>
#include <mutex>
#include <condition_variable>
#define _dbg(fmt,...) do {printf("[Dbg][%s:%d] " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);} while(0)
class AA {
public:
AA() {
mData = sCount ++;
_dbg("data %u", mData);
}
~AA() {
_dbg("data %u", mData);
}
unsigned data() const { return mData; }
private:
unsigned mData;
static unsigned sCount;
};
unsigned AA::sCount = 0;
struct proc_context {
bool mRunFlag;
std::list< std::shared_ptr<AA> > mQueue;
std::mutex mMutex;
std::condition_variable mCond;
};
static void proc_producer(struct proc_context& ctx)
{
_dbg("enter");
for (;ctx.mRunFlag;) {
{
std::unique_lock<std::mutex> lck(ctx.mMutex);
std::shared_ptr<AA> a = std::make_shared<AA>();
_dbg("push data %u", a->data());
ctx.mQueue.push_back(a);
ctx.mCond.notify_one();
}
std::this_thread::sleep_for(std::chrono::microseconds(100000));
}
_dbg("leave");
}
static void proc_consumer(struct proc_context& ctx)
{
_dbg("enter");
for (;ctx.mRunFlag;) {
std::unique_lock<std::mutex> lck(ctx.mMutex);
ctx.mCond.wait_for(lck, std::chrono::microseconds(500000), [&]()->bool {
return !ctx.mQueue.empty();
});
if (!ctx.mQueue.empty()) {
std::shared_ptr<AA> a = ctx.mQueue.front();
ctx.mQueue.pop_front();
_dbg("pop data %u", a->data());
}
}
_dbg("leave");
}
int main()
{
_dbg("enter");
struct proc_context ctx;
ctx.mRunFlag = true;
std::thread t0 = std::thread(proc_producer, std::ref(ctx));
std::this_thread::sleep_for(std::chrono::seconds(1));
std::thread t1 = std::thread(proc_consumer, std::ref(ctx));
std::this_thread::sleep_for(std::chrono::seconds(10));
ctx.mRunFlag = false;
t0.join();
t1.join();
_dbg("leave");
return 0;
}