6

IPC (inter process communication)シグナルキャッチとシグナルレイズを使って行うことは可能ですか?

プログラムを2つ作りました。最初のプログラムではシグナルの処理を行い、別のプログラムでは別のプログラムで処理したいシグナルを発生させました。私はうまくいきませんが、信号を使用してこれら2つのプログラム間で通信を行い、このraise信号でいくつかのバイトのデータを送信したいと考えています。これどうやってするの?

このシグナルでもメッセージを渡したいです。私はそれを行うことができますか?可能です?

また、シグナルを使用した IPC メカニズムの短所と利点は何ですか?

以下は、私の2つのプログラムの作業コードです。これで、シグナルを発生させてシグナルをキャッチすることはできますが、あるプログラムから別のプログラムにデータを渡したいです。

2 番目のプログラムでは、最初のプログラムのプロセス 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);
    }

}
4

5 に答える 5

14

シグナルは、IPCメカニズムとしてではなく、プロセスに対する基本的な制御を提供することを目的としています。シグナルを他のものとして使用する場合、いくつかの問題があります。

  • 多くのシステムコールはシグナルによって中断され、特別な処理が必要になります。

  • したがって、実際のコードの多くはシグナルセーフではありません。

  • シグナルには、それ自体を除いて、いかなる種類のデータコンテンツも含まれていません。これにより、メッセージパッシングメソッドとしてはほとんど役に立たなくなります。

  • シグナルハンドラでできることはたくさんあります。

  • 最も重要なのは、同じタイプの後続のシグナルがキューに入れられないことです。これらは1つのインスタンスにマージされます。

  • さらに重要なのは、信号が生成されたのと同じ順序で配信されるという保証はありません。マニュアルページから:

    対照的に、プロセスに対して複数の標準シグナルが保留中の場合、それらが配信される順序は指定されていません

理論的には、ある種の確認応答のように動作するいくつかの信号を使用して、ある種のチャネルを設定できる可能性がありますが、正気の人はそのようなことを試みたくないでしょう。代わりに煙信号を使用する方がよいでしょう...

于 2012-06-21T09:06:08.560 に答える
4

シグナルキャッチとシグナルレイズを使用してIPC(プロセス間通信)を行うことは可能ですか?

はいといいえ。シグナルのみを考慮すると、別のプロセスにシグナルを送信することはできますが、シグナル以外のものを送信することはできません。

この信号でメッセージを渡したいです。できますか?可能です?

いいえ、あなたがしようとしている方法ではありません。これを行うには、ソケット、ファイル、パイプ、または名前付きパイプを使用できます。UNIX IPCの詳細については、UNIX環境での高度なプログラミングを参照してください

于 2012-06-21T08:07:31.937 に答える
4

いいえ、これに信号を使用しようとしないでください。siginfo 構造体以外のシグナルに余分なデータを添付することはできません。ただし、シグナルを使用する際の主な問題は、シグナルセーフがほとんどないことです。ほぼすべての C ランタイム ルーチンを回避し、受信プログラムがすべてのカーネル呼び出しで EINTR チェックを行うようにする必要があります。信号がいつ発生するかについて言えることは、期待したときに発生しないということだけです (スペインの異端審問に少し似ています)。

共有メモリ、メッセージ キュー、FIFO (名前付きパイプ)、ソケットなど、他の IPC メカニズムを調べることをお勧めします。

于 2012-06-21T08:09:34.947 に答える
2

私が遭遇したある特定のケースを除いて、シグナルは一般に IPC メカニズムとしては役に立ちません。

私がシグナルを使用したのは、IPC メカニズムの一部として、タイマー割り込みなど、何かを処理するためにシグナルされたプロセスの通常の動作フローを中断する必要があるときだけでした。シグナル ( はシグナルをブースト共有メモリーと共に使用して、プロセス間イベント管理を実装しています。共有メモリーには、処理が必要なイベントのリストが含まれており、シグナルは、プロセスにこれらのイベントを処理させるために使用されます。これらのイベントは帯域外です。私はかなりのテストを実行して実装を検証しました (そして、すべてを安定させるのは困難でした)。

これは、glibc を使用する Linux 環境でシグナル SIGRTMIN+1 と一緒に sigqueue を使用し、sigaction で SA_RESTART を使用すると、EINTR を直接処理する必要がなくなります。 glibc: Primitives Interrupted by Signalsを参照してください。BSD にも同様のスキームがあるため、私のシステムでは EINTR 処理は必要ありませんでした。他の回答によって指摘されたすべての点が考慮され、処理されました (そしてテストされました)。

ただし、プロセスの通常の操作で値を前後に渡したいだけの場合は、ソケット、ファイル、パイプ、名前付きパイプなどの別の IPC の方が適しています。ZeroMQを使用できる場合は、非常にエレガントな方法で多くのハードワークを実行できるため、さらに優れています。

于 2012-06-21T08:58:22.663 に答える