在 linux 上使用信号的 IPC

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11133887/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 06:59:52  来源:igfitidea点击:

IPC using Signals on linux

clinuxsignalsipc

提问by user1089679

It is possible to do IPC (inter process communication)using signal catch and signal raise?

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

I made two programs. In the first program I did handling of signals, and in the other program I just raised signal which I want to handle in another program. I'ts working fine for me but I want to do communication between these two programs using signals and also want to send some bytes of data with this raise signal. How can I do this?

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

I want to pass messages with this signal also. Can i do it? It is possible?

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

And also, what are the disadvantages and advantages of IPC mechanisms using signals?

还有,使用信号的 IPC 机制的优缺点是什么?

The following is working code of my two programs. Ising this, I am able to just raise signals and catch signals, but I want to pass data from one program to another.

以下是我的两个程序的工作代码。这样做,我只能发出信号并捕获信号,但我想将数据从一个程序传递到另一个程序。

In the second program, I used the first program's process ID. How can I make it dynamic.?

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

first program :

第一个程序:

/* 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;
}

second program

第二个节目

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

void  main(void)
{

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

}

采纳答案by thkala

Signalsare intended to provide a rudimentary form of control over a process, not as an IPC mechanism. Signals have several issues when used as anything else:

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

  • A lot of system calls will be interrupted by a signal and need special handling.

  • Accordingly, a lot of code in the wild is not signal-safe.

  • Signals do not have any kind of data content, except for themselves. This makes them mostly useless as a message passing method.

  • There is only so much you can do in a signal handler.

  • Most importantly, subsequent signals of the same type are not queued - they are mergedinto one instance.

  • Even more important, there is no guarantee that signals are delivered in the same order as they were generated. From the manual page:

    By contrast, if multiple standard signals are pending for a process, the order in which they are delivered is unspecified.

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

  • 因此,大量的代码不是信号安全的。

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

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

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

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

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

You might theoreticallybe able set up some kind of channel using several signals going back and forth, with some acting like some sort of acknowledgement, but no sane person would want to attempt something like that. You might as well use smoke signals instead...

理论上讲,您可以使用几个来回传递的信号来建立某种通道,其中一些信号表现得像是某种确认,但没有理智的人会想要尝试这样的事情。你还不如用烟雾信号代替...

回答by Jay Sullivan

It is possible to do IPC (inter process communication) using signal catch and signal raise?

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

Yes and no. Considering signals only, you can send a signal to another process, but you can't send anything other than just a signal.

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

I want to pass messages with this signal also. Can i do it? It is possible?

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

No, not the way you're trying to. You can use sockets, files, pipes, or named pipes to do this. If you want to learn more about UNIX IPC, read Advanced Programming in the UNIX Environment.

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

回答by cdarke

No, don't try and use signals for this. You cannot attach extra data with signals other than the siginfo struct. The main problem with using signals though is that so little is signal safe. You have to avoid just about all the C runtime routines, and make sure the recieving program does EINTR checks on all its kernel calls. The only thing you can say about when a signal occurs is that it won't be when you expect it (a bit like the Spanish Inquisition).

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

I suggest you look into the other IPC mechanisms, such as shared memory, message queues, fifos (named pipes), and sockets.

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

回答by Richard Harrison

Except in one specific case that I've encountered signals aren't generally useful as IPC mechanism.

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

The only time I've used signals was as part of an IPC mechanism when you need to interrupt the normal flow of operation of the signalled process to handle something, for example a timer interrupt. The signal ( have used signals together with boost shared memory to implement interprocess event management. The shared memory contains a list of events that need processing and the signal is used to get the process to process these events. These events are out-of-band and unpredictable so using a signal was ideal. I performed considerable testing to verify the implementation (and it was hard to get it all stable).

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

This used sigqueue together with signal SIGRTMIN+1 in a Linux environment using glibc and using SA_RESTART on the sigaction will avoid the need to directly handle EINTR see glibc: Primitives Interrupted by Signals. BSD has a similar scheme so EINTR handling wasn't required in my system. All of the points made by the other answers were considered and handled (and tested).

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

However if you just want to pass values back and forwards within the normal operation of the process then another IPC such as sockets, files, pipes or named pipes are better. If you can use ZeroMQthen even better as that does a lot of the hard work for you in a very elegant way.

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

回答by Ladon

I'm currently reading man 7 signal:

我目前正在阅读man 7 signal

Real-time signals are distinguished by the following:

  1. If the signal is sent using sigqueue(3), an accompanying value (either an integer or a pointer) can be sent with the signal. ...

实时信号的区别如下:

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

Note: Real-time signals start from SIGRTMINto SIGRTMAX.

注意:实时信号从SIGRTMINSIGRTMAX