如何在主进程和线程之间使用Unix管道?

时间:2009-06-08 15:00:30

标签: c++ multithreading pipe unix

每当信号从线程到达主进程时,我都试图通过管道传输数据。

这可能吗?
怎么办呢?


问题:

  1. 子线程读取数据并将其放入队列中。
  2. 主应用程序有自己的功能,但是,当队列中有数据时,它应该被线程通知,并开始处理数据(主线程可以访问队列)。
  3. 如何实施此方案?

5 个答案:

答案 0 :(得分:13)

是的,可以通过管道。

第一步致电pipe以获得管道:

  #include <unistd.h>


  int main(...)
  {

    int fileDescriptors[2];
    pipe(fileDescriptors);

步骤2将fileDescriptors [0]传递给主进程,将fileDescriptors 1传递给线程。在Main中,您可以通过从fileDescriptors [0]

读取来等待管道写入
    ...
    char msg[100];
    read(fileDescriptors[0], msg, 100);  // block until pipe is read
  }

步骤3,当信号发生时从你的线程写入fileDescritpors 1

 void signal_handler( int sig )
 {
     // Write to the file descriptor
     if (sig == SIGKILL)
     {
         const char* msg = "Hello Mama!";
         write(fileDescriptors[1], msg, strlen(msg));
     }
 }

答案 1 :(得分:4)

可以做到,但这是不必要的。管道用于进程间通信。线程共享相同的内存,因此只要您正确使用锁定,就可以直接进行通信。

答案 2 :(得分:1)

如果您正在谈论pipe()而不是|,那么是的。管道通常只能被视为文件描述符。您只需打开管道并清除一个线程中的输入,另一个线程中的输出。

答案 3 :(得分:0)

正如其他人所说,这可能比它的价值更麻烦。

但是,如果你坚持。

在生成线程之前,使用popenrw模式打开两个管道可能最容易。选择一个用于main - &gt;线程,另一个用于main&lt; - thread,然后继续。

或者你可以在产生后打开总共四个文件描述符,就像它们是两个不同的进程一样

答案 4 :(得分:0)

你可以这样做,apache有一个类似的“优雅重启”选项。 (见here)。你会使用类似的东西:

#include <sys/types.h>
#include <signal.h>

kill(getppid(), SIGUSR1);

向父母发送信号。其他人使用上面的代码来生成文件描述符并在父端捕获它。

但是,我倾向于避免脚本化进程间通信的信号,而是仅将它们用于“用户发送”消息,例如启动/停止/重新启动/刷新。你替换它们取决于你的用例:你可以使用一个消息传递变量,或者如果你的主进程在服务器循环中,你可以在循环顶部的管道上"select"查看该子进程是否有发送了刷新消息。可能还有很多其他我不知道的。