#include <deque>
#include <string>
#include <mutex>
#include <condition_variable>
#include <memory>
#include <iostream>
#include <utility>
using namespace std::chrono_literals;
class MessageManager {
public:
explicit MessageManager(int maxNum) : mMaxNum(maxNum) {
}
~MessageManager() = default;
public:
void pushMessage(const std::string &msg) {
std::unique_lock<std::mutex> lock{
mMutex};
if (mMsgQueue.size() >= mMaxNum) {
mCond.wait(lock, [=] {
return mMsgQueue.size() < mMaxNum; });
}
mMsgQueue.push_back(msg);
mCond.notify_one();
}
std::string popMessage() {
std::unique_lock<std::mutex> lock{
mMutex};
if (mMsgQueue.empty()) {
mCond.wait(lock, [=] {
return !mMsgQueue.empty(); });
}
std::string msg = mMsgQueue.front();
mMsgQueue.pop_front();
mCond.notify_one();
return msg;
}
private:
std::deque<std::string> mMsgQueue;
int mMaxNum{
10};
std::mutex mMutex;
std::condition_variable mCond;
};
class MsgSender {
public:
MsgSender(std::string name, std::shared_ptr<MessageManager> msgManager)
: mName(std::move(name)), mMsgManager(msgManager) {
}
~MsgSender() {
mStop = true;
if (mThread && mThread->joinable()) {
mThread->join();
}
}
public:
void start() {
if (mThread) {
mStop = true;
if (mThread->joinable()) {
mThread->join();
}
}
mStop = false;
mThread = std::make_unique<std::thread>(&MsgSender::doSend, this);
}
public:
void stop() {
mStop = true;
}
private:
void doSend() {
while (!mStop) {
std::string msg = std::to_string(msgId++);
mMsgManager->pushMessage(msg);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << "Sender:" << mName << " has stop.\n";
}
private:
std::string mName;
int msgId{
0};
std::shared_ptr<MessageManager> mMsgManager;
std::unique_ptr<std::thread> mThread{
nullptr};
std::atomic_bool mStop{
false};
};
class MsgReceiver {
public:
MsgReceiver(std::string name, std::shared_ptr<MessageManager> msgManager)
: mName(std::move(name)), mMsgManager(msgManager) {
}
~MsgReceiver() {
mStop = true;
if (mThread && mThread->joinable()) {
mThread->join();
}
}
public:
void start() {
if (mThread) {
mStop = true;
if (mThread->joinable()) {
mThread->join();
}
}
mStop = false;
mThread = std::make_unique<std::thread>(&MsgReceiver::doReceive, this);
}
public:
void stop() {
mStop = true;
}
private:
void doReceive() {
while (!mStop) {
std::string msg = mMsgManager->popMessage();
std::cout << "msg:" << msg << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << "Receiver:" << mName << " has stop.\n";
}
private:
std::string mName;
int msgId{
0};
std::shared_ptr<MessageManager> mMsgManager;
std::unique_ptr<std::thread> mThread{
nullptr};
std::atomic_bool mStop{
false};
};
void testRun() {
std::shared_ptr<MessageManager> msgManager = std::make_shared<MessageManager>(1);
MsgSender sender{
"1", msgManager};
MsgReceiver receiver{
"1", msgManager};
sender.start();
receiver.start();
std::this_thread::sleep_for(10s);
std::cout << "...testRun end ...\n";
}
C++线程:生产者消费者模式
猜你喜欢
转载自blog.csdn.net/xiwenhec/article/details/129701200
今日推荐
周排行