7

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

这可能吗?
如何才能做到这一点?


问题:

  1. 子线程读取数据并将其放入队列中。
  2. 主应用程序做自己的事情,但是,当队列中有数据可用时,它应该由线程通知,并开始处理数据(主线程可以访问队列)。

这个场景应该如何实现?

4

5 回答 5

14

是的,它可以通过管道。

第一步调用管道获取管道:

  #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));
     }
 }
于 2009-06-08T15:11:20.283 回答
4

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

于 2009-06-08T15:09:29.973 回答
1

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

于 2009-06-08T15:12:42.400 回答
0

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

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

kill(getppid(), SIGUSR1);

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

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

于 2009-06-08T15:32:48.040 回答
0

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

但是,如果你坚持。

可能最简单的方法是在生成线程之前使用popenand模式打开两个管道。rw为 main-->thread 选择一个,为 main<--thread 选择另一个,然后继续。

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

于 2009-06-08T15:19:16.490 回答