IPC在linux上使用信号

时间:2012-06-21 07:59:50

标签: c linux signals ipc

可以使用信号捕获和信号提升来进行IPC (inter process communication)吗?

我制作了两个节目。在第一个程序中,我处理了信号,而在另一个程序中,我只是提出了我想在另一个程序中处理的信号。我工作正常,但我希望使用信号在这两个程序之间进行通信,并且还希望使用此提升信号发送一些字节数据。我怎么能这样做?

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

此外,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);
    }

}

5 个答案:

答案 0 :(得分:13)

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

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

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

  • 信号没有任何类型的数据内容,除了他们自己。这使得它们作为消息传递方法大多无用。

  • 您只能在信号处理程序中执行此操作。

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

  • 更重要的是,无法保证信号的传递顺序与生成时相同。从手册页:

      

    相比之下,如果某个过程有多个标准信号待处理,其中的顺序   他们的交付是未指定的

你理论上可以能够使用几个来回的信号设置某种通道,有些表现得像某种确认,但没有理智的人会想要尝试这样的事情。你不妨使用烟雾信号......

答案 1 :(得分:4)

  

可以使用信号捕获和信号提升来进行IPC(进程间通信)吗?

是和否。仅考虑信号,您可以向另一个进程发送信号,但除了信号之外,您不能发送任何信号。

  

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

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

答案 2 :(得分:3)

不,不要尝试使用信号。您不能使用siginfo结构以外的信号附加额外数据。然而,使用信号的主要问题是信号安全性很小。您必须避免几乎所有C运行时例程,并确保接收程序对其所有内核调用执行EINTR检查。关于信号何时出现,你唯一可以说的是它不会在你预期的时候出现(有点像西班牙宗教裁判所)。

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

答案 3 :(得分:2)

除了一个特殊情况,我遇到的信号通常不适用于IPC机制。

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

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

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

答案 4 :(得分:0)

我正在阅读man 7 signal

  

实时信号的特征如下:

     
      
  1. 如果使用sigqueue(3)发送信号,则可以将伴随值(整数或指针)与信号一起发送。 ...
  2.   

注意:实时信号从SIGRTMINSIGRTMAX开始。