使用命令文件在线程之间传递消息 [英] Message passing between threads using a command file

查看:79
本文介绍了使用命令文件在线程之间传递消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

该项目要求4个线程的命令文件包含 指令,例如发送,接收和退出.当文件说"2 发送"该数组第二个位置应唤醒的线程 并接收其消息.我需要知道如何使线程读取 如果命令文件中有消息,则为消息?

This project asked for 4 threads that has a command file with instructions such as SEND, Receive and quit. When the file says "2 send" the thread that in the second place in the array should wake up and receive its message. I need to know how to make a thread read it's message if the command file has a message for it?

推荐答案

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

The biggest issue I see for your design is the fact that each thread reads its line randomly independent from any other thread. After this it would have to check wether the current line is actually meant for it i.e. starting with the appropriate number. What happens if not ? Too complicated.

我将把这个问题分成一个 reader 线程和一组 worker 线程.第一个从文件中读取行,并通过将其推送到当前工作程序队列中来将其分派给工作程序.所有这些都与每个工人互斥体和条件变量同步.以下是在C ++ 11中实现的,但也应该以pthread_ *样式实现.

I would split this issue up into one reader thread and a set of worker threads. The first reads lines from a file and dispatches it to the workers by pushing it into the current workers queue. All synchronized with a per worker mutex and conditional variable The following is implemented in C++11 but should as well be doable in 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而言是不可行的.

The example code only reads from "commands.txt" until EOF. I assume you'd like to read continuously like the "tail -f" command. That's however not doable with std::istream.

代码当然很笨拙,但是我想它给了你一个主意.例如,如果工作人员处理他们的东西的速度太慢并且队列可能耗尽了所有宝贵的RAM,则应该添加一种阻塞机制.

The code of course is clumsy but I guess it gives you an idea. One should for example add a blocking mechanism if the workers are way too slow processing their stuff and the queues may eat up all the precious RAM.

这篇关于使用命令文件在线程之间传递消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆