在没有系统调用(管道)的线程之间使用 std::istream 和 std::ostream

Posted

技术标签:

【中文标题】在没有系统调用(管道)的线程之间使用 std::istream 和 std::ostream【英文标题】:Use std::istream and std::ostream between threads without system calls (pipe) 【发布时间】:2019-10-05 21:48:40 【问题描述】:

我正在寻找一种使用<iostream> 语义在线程之间创建通信流的简单方法。我正在寻找类似以下的内容:

#include <iostream>
#include <thread>

void thread1(std::istream from_main, std::ostream to_main) 
    std::string s;
    from_main >> s;
    to_main << "Received:" << s << std::endl;

int main() 
   std::istream from_thread;
   std::ostream to_thread;
   std::thread t(thread1, to_thread, from_thread);
   to_thread << "Hi-Thread\n";
   std::string s;
   from_thread >> s; // Received:Hi-Thread
   t.join();

有没有不使用pipe、创建文件描述符和用系统调用填充代码的简单方法?

【问题讨论】:

我很好奇您为什么需要管道、fds 和系统调用来执行此操作?一切都在同一个进程中,所以你可以有一个消息队列和一个锁,对吧?这里的用例是什么? @ggorlen 是的,但我想念整个std::stream 语义,这非常好。 你的队列可以覆盖&lt;&lt;&gt;&gt; 运算符。 @ggorlen 我当然可以,但这会给我带来各种错误的可能性。如果没有更标准的解决方案,我会感到非常惊讶。 似乎定义一个具有必要行为的std::streambuf 的子类相当简单。你可以构造一个 istream 和 ostream 来引用它。 【参考方案1】:

看起来您需要的是一个单生产者、单消费者 (SPSC) 队列,可能是无锁的。我会从这个开始,如果你觉得非常需要构建语法糖来使operator&lt;&lt; 意味着spsc_queue::push_back,稍后再添加。不要从 C++ operator &lt;&lt; 语法的角度出发,然后认为“哦,这意味着 std::ostream”,然后会导致“让我们自定义 streambuf。”

保持简单。 SPSC queue.

【讨论】:

以上是关于在没有系统调用(管道)的线程之间使用 std::istream 和 std::ostream的主要内容,如果未能解决你的问题,请参考以下文章

java多线程通过管道流实现不同线程之间的通信

多线程之间的通信~~~管道通道

c++ 如何在构造函数中启动一个线程,从命名管道读取数据?

linux用户空间 - 多进程编程(三)

linux面试

查漏补缺:进程间通信(IPC):管道