4

いくつかのPOSIXコードをテストしたところ、信号の利用があまり正確ではないことに気づきました。クライアントのサンプルコードは次のとおりです。

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

#define MESSAGE "hello\n"
#define PAUSE   15000

int main(int argc, char **argv)
{
    int pid = atoi(argv[1]);
    size_t i;
    int j;

    for (i = 0; i < sizeof MESSAGE; ++i) {
        for (j = 0; j < MESSAGE[i]; ++j) {
            kill(pid, SIGUSR1);
            usleep(PAUSE);
        }
        kill(pid, SIGUSR2);
        usleep(PAUSE);
    }
    return 0;
}

サーバーのコードは次のとおりです。

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

static unsigned char index;

static void inc(int sig)
{
    ++index;
    (void) sig;
}

static void prt(int sig)
{
    printf("%c", index);
    fflush(stdout);
    index = 0;

    (void) sig;
}

int main(void)
{
    printf("%ld\n", (long int)getpid());

    signal(SIGUSR1, inc);
    signal(SIGUSR2, prt);

    for (;;)
        ;

    return 0;
}

PAUSEサーバーが受け取る文字は、クライアントの値によって異なります。それは信号の限界から来ているのですか、それとも私はエラーを犯しましたか?もしそうなら、これらの環境への配慮はどこにありますか(私はLinux 2.6.35を使用しています)?

注意:クライアントのコードを実行するには、サーバーのPIDをコマンドライン引数で記述する必要があります。

4

1 に答える 1

7

この種のプロセス間通信は、信じられないほど非効率的であるだけではありません。それも無効です。シグナルはキューに入れられません。保留中または保留中ではありません(*)。したがって、送信者が別のシグナルを送信する前に受信者のプロセスがシグナルを読み取らない限り、シグナルは失われます。

このような恐ろしいことを本当にしたい場合、受信者は送信者に信号を送り返すことによって受信する各信号を確認する必要があり、送信者は前の信号が確認されるまで次の信号を送信するのを待つ必要があります。

(*)実際には、リアルタイムシグナルはキューに入れられますが、キューの深さには制限があり、キューがオーバーランしないようにするには、苦痛で壊れやすいリアルタイム優先度管理ロジックが必要になります。

于 2012-11-18T17:21:17.950 に答える