2014-11-14 48 views
0

该项目需要4个线程,其中包含 命令文件,如SEND,Receive和quit。当文件说“2 发送”时,阵列中第二位的线程应该唤醒 并收到它的消息。我需要知道如何让线程读取 如果命令文件中有消息,它就是消息?使用命令文件在线程之间传递消息

+0

在C++ 11线程库上使用pthread有什么好处吗? – sjdowling

+1

呃?当然,这是处理IPC的一种非常愚蠢的方式吗? –

+0

为什么你会使用文件?也许如果你正在处理多个**进程**,但为什么当他们只是线程? – CoffeeandCode

回答

1

我看到你的设计中最大的问题是每个线程都从其他线程中随机读取它的行。在此之后,必须检查当前线路实际上是否意味着它,即从适当的号码开始。如果不是,会怎样?太复杂。

我会将此问题分为一个读者线程和一套工作者线程。第一行读取文件中的行,并通过将其推送到当前的工作队列中来将其分派给工作人员。全部与每个工人互斥和条件变量同步以下是在C++ 11中实现的,但也应该在pthread_ * style中实现。

#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,则应该添加阻塞机制。

+1

“例如,如果工作人员处理他们的东西太慢,队列可能会吃掉所有珍贵的RAM,则应该添加阻塞机制。”听起来像[TBB并发有限队列]的工作(http://www.threadingbuildingblocks.org/docs/help/reference/containers_overview/concurrent_bounded_queue_cls.htm) – sjdowling

+0

@sjdowling对我来说看起来不错。 – Oncaphillis