使用命令文件在线程之间传递消息

时间:2014-11-14 06:58:12

标签: c++ multithreading message-passing

这个项目要求4个带有命令文件的线程     SEND,Receive和quit等说明。当文件说" 2     发送"数组中第二个位置的线程应该唤醒     起来并收到它的消息。我需要知道如何读取线程     如果命令文件有消息,它的消息是什么?

1 个答案:

答案 0 :(得分:1)

我为您的设计看到的最大问题是每个线程随机独立于任何其他线程读取其行。在此之后,它必须检查当前行是否实际意味着它,即从适当的数字开始。如果没有会发生什么?太复杂。

我会将此问题分解为一个 reader 主题和一组 worker 主题。第一个从文件中读取行,并通过将其推送到当前工作队列来将其分派给工作者。全部与每个工作者互斥和条件变量同步以下内容在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(); 
} 

示例代码仅从&#34; commands.txt&#34;直到EOF。我假设你想像#&#34; tail -f&#34;命令。然而,对于std :: istream来说,这是不可行的。

代码当然是笨拙的,但我想它会给你一个想法。例如,如果工作人员处理他们的东西太慢而队列可能会占用所有宝贵的RAM,那么应该添加阻塞机制。