繁体   English   中英

IPC 在 Linux 上使用 Signals

[英]IPC using Signals on linux

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

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

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

另外,使用信号的 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);
    }

}

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

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

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

  • 信号除了自身之外没有任何类型的数据内容。 这使得它们作为消息传递方法几乎毫无用处。

  • 在信号处理程序中您只能做这么多。

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

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

    相比之下,如果一个进程有多个标准信号待处理,则它们的传递顺序是未指定的

理论上讲,您可以使用多个信号来回设置某种通道,其中一些信号就像某种确认,但没有一个理智的人愿意尝试这样的事情。 您不妨改用烟雾信号...

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

是和不是。 仅考虑信号,您可以向另一个进程发送信号,但不能发送信号以外的任何东西。

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

不,不是你想要的方式。 您可以使用套接字、文件、管道或命名管道来执行此操作。 如果您想了解有关 UNIX IPC 的更多信息,请阅读UNIX 环境中的高级编程

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

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

除了在一种特定情况下,我遇到过信号通常不用作 IPC 机制。

我唯一一次使用信号是作为 IPC 机制的一部分,当您需要中断信号进程的正常操作流程以处理某些事情时,例如定时器中断。 signal( 已经使用 signals 和 boost shared memory 一起实现进程间事件管理。共享内存包含需要处理的事件列表,signal 用于让进程处理这些事件。这些事件是 out-of-band并且不可预测,所以使用信号是理想的。我进行了大量测试来验证实现(并且很难让它全部稳定)。

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

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

我目前正在阅读man 7 signal

实时信号有以下区别:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM