簡體   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