C++线程:生产者消费者模式

#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";
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值