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";
}

猜你喜欢

转载自blog.csdn.net/xiwenhec/article/details/129701200