[英]Message passing between threads using a command file
该项目要求使用4个线程,这些线程具有一个带有诸如SEND,Receive和quit之类的指令的命令文件。 当文件说“ 2 send”时,位于阵列第二位的线程应唤醒并接收其消息。 如果命令文件中有消息,我需要知道如何使线程读取它的消息?
对于您的设计,我看到的最大问题是每个线程随机地独立于任何其他线程读取其行。 此后,必须检查是否当前行实际上是针对它的,即以适当的数字开头。 如果没有,会发生什么? 太复杂。
我将把这个问题分成一个阅读器线程和一组工作线程。 第一个从文件中读取行,并通过将其推入当前工作程序队列将其分派给工作程序。 所有这些都与每个工作程序互斥体和条件变量同步。以下是在C ++ 11中实现的,但也应该以pthread_ *样式实现。
#include <thread>
#include <iostream>
#include <queue>
#include <mutex>
#include <fstream>
#include <list>
#include <sstream>
#include <condition_variable>
class worker {
public:
void operator()(int n) {
while(true) {
std::unique_lock<std::mutex> l(_m);
_c.wait(l);
if(!_q.empty()) {
{
std::unique_lock<std::mutex> l(_mm);
std::cerr << "#" << n << " " << _q.back() <<std::endl;
}
_q.pop();
}
}
}
private:
std::mutex _m;
std::condition_variable _c;
std::queue<std::string> _q;
// Only needed to synchronize I/O
static std::mutex _mm;
// Reader may write into our queue
friend class reader;
};
std::mutex worker::_mm;
class reader {
public:
reader(worker & w0,worker & w1,worker & w2,worker & w3) {
_v.push_back(&w0);
_v.push_back(&w1);
_v.push_back(&w2);
_v.push_back(&w3);
}
void operator()() {
std::ifstream fi("commands.txt");
std::string s;
while(std::getline(fi,s)) {
std::stringstream ss(s);
int n;
if((ss >> n >> std::ws) && n>=0 && n<_v.size()) {
std::string s0;
if(std::getline(ss,s0)) {
std::unique_lock<std::mutex> l(_v[n]->_m);
_v[n]->_q.push(s0);
_v[n]->_c.notify_one();
}
}
}
std::cerr << "done" << std::endl;
}
private:
std::vector<worker *> _v;
};
int main(int c,char **argv) {
worker w0;
worker w1;
worker w2;
worker w3;
std::thread tw0([&w0]() { w0(0); });
std::thread tw1([&w1]() { w1(1); });
std::thread tw2([&w2]() { w2(2); });
std::thread tw3([&w3]() { w3(3); });
reader r(w0,w1,w2,w3);
std::thread tr([&r]() { r(); });
tr.join();
tw0.join();
tw1.join();
tw2.join();
tw3.join();
}
该示例代码仅从“ commands.txt”读取,直到EOF。 我假设您想像“ tail -f”命令一样连续阅读。 但是,这对于std :: istream而言是不可行的。
代码当然很笨拙,但我想它给了您一个主意。 例如,如果工作人员处理他们的东西的速度太慢并且队列可能耗尽了所有宝贵的RAM,则应该添加一种阻塞机制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.