2012-06-21 33 views
4

使用信号捕获和信号上升可以做IPC (inter process communication)使用linux上的信号的IPC

我做了两个程序。在第一个程序中,我处理了信号,而在另一个程序中,我只是提出了我想在另一个程序中处理的信号。我对我的工作很好,但我想使用信号在这两个程序之间进行通信,并且还希望通过该提升信号发送一些字节的数据。我怎样才能做到这一点?

我想用这个信号也传递消息。我可以做吗?有可能的?

而且,使用信号的IPC机制有什么缺点和优点?

以下是我的两个程序的工作代码。就此而言,我只能提高信号和捕获信号,但我想将数据从一个程序传递到另一个程序。

在第二个程序中,我使用了第一个程序的进程ID。我怎样才能让它变成动态的?

第一程序:

/* Example of using sigaction() to setup a signal handler with 3 arguments 
* including siginfo_t. 
*/ 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <signal.h> 
#include <string.h> 

static void hdl (int sig, siginfo_t *siginfo, void *context) 
{ 
    printf("sig no = %d \n", sig); 
    if(sig == SIGINT) 
     exit(0); 
    printf ("Sending PID: %ld, UID: %ld\n", 
      (long)siginfo->si_pid, (long)siginfo->si_uid); 
} 

int main (int argc, char *argv[]) 
{ 
    struct sigaction act; 


    sigemptyset(&act.sa_mask); 

    act.sa_sigaction = &hdl; 
    act.sa_flags = SA_SIGINFO; 

    if (sigaction(SIGUSR1, &act, NULL) < 0) { 
     perror ("sigaction SIGUSR1"); 
     return 1; 
    } 
    if (sigaction(SIGINT, &act, NULL) < 0) { 
     perror ("sigaction SIGINT"); 
     return 1; 
    } 

    while (1) 
    { 
     sleep(1); 
    } 

    return 0; 
} 

第二程序

#include <stdio.h> 
#include <signal.h> 

void main(void) 
{ 

    while (1) 
    { 
     sleep(1); 
     kill(11558, SIGUSR1); 
    } 

} 
+0

我会推荐_against_使用相同的信号处理程序来处理'SIGINT'和'SIGUSR1'等信号。尽可能分开信号处理程序。 –

+0

@JoachimPileborg我怎么能做到这一点可以请给我链接或一些教程,我在Google上发现很多,但我没有得到任何东西。 – user1089679

+0

只需对两个不同的调用使用两个不同的'sigaction'结构,每个调用都有自己的处理函数。 –

回答

11

Signals旨在提供对过程的基本形式控制,而不是IPC机制。当用作其他信号时,信号有几个问题:

  • 许多系统调用会被信号中断,需要特殊处理。

  • 因此,野外很多代码都不是信号安全的。

  • 信号没有任何形式的数据内容,除了它们自己。这使得它们几乎无用作为消息传递方法。

  • 只有你可以在信号处理程序中做很多事情。

  • 最重要的是,相同类型的后续信号不排队 - 它们是合并为为一个实例。

  • 更重要的是,不能保证信号的发送顺序与它们生成的顺序相同。从手动页面:

    相反,如果多个标准信号未决的方法,的顺序 它们递送是未指定

你可能理论上能够建立某种使用多种信号来回,有一些表演像某种确认的通道,但没有理智的人会想尝试类似的东西。你可以使用烟雾信号代替...

4

有可能使用信号捕获做IPC(进程间通信)和信号加注?

是,也不是。只考虑信号,你可以发送一个信号给另一个进程,但你不能发送除信号以外的任何东西。

我想用这个信号也传递消息。我可以做吗?有可能的?

不,不是你想要的样子。您可以使用套接字,文件,管道或命名管道来执行此操作。如果您想了解更多关于UNIX IPC的信息,请阅读Advanced Programming in the UNIX Environment

+0

我认为UNIX环境下的高级编程有第二版。 – Shash

2

不,请不要尝试使用此信号。您不能使用siginfo结构以外的其他信号附加额外的数据。尽管使用信号的主要问题是信号安全如此之少。您必须避免几乎所有的C运行时例程,并确保接收程序确保EINTR检查其所有内核调用。当信号发生时,唯一可以说的就是它不会在你期望的时候出现(有点像西班牙宗教裁判所)。

我建议你看看其他IPC机制,例如共享内存,消息队列,fifos(命名管道)和套接字。

1

除了在遇到信号的一个特定情况下,IPC机制通常不会有用。

我唯一使用信号的时间是当你需要中断正常信号处理操作流程来处理某些事情时,例如定时中断,作为IPC机制的一部分。信号(已经使用信号和boost共享内存来实现进程间事件管理,共享内存包含需要处理的事件列表,并且信号用于让进程处理这些事件。这些事件是带外和不可预测的,因此使用信号是理想的。我执行了相当多的测试来验证实现(并且很难使其全部稳定)。

在Linux环境中使用sigqueue和signal SIGRTMIN + 1,使用glibc并在sigaction上使用SA_RESTART将避免直接处理EINTR的需要,请参阅glibc: Primitives Interrupted by Signals。 BSD有一个类似的方案,所以在我的系统中不需要EINTR处理。所有其他答案提出的观点都被考虑和处理(并经过测试)。

但是,如果您只想在进程的正常操作内传递值,则另一个IPC(例如套接字,文件,管道或命名管道)会更好。如果你可以使用ZeroMQ那么更好,因为它以非常优雅的方式为你做了很多艰苦的工作。