杀戮和信号有多准确?

时间:2012-11-18 16:52:10

标签: c linux signals

测试一些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。

1 个答案:

答案 0 :(得分:7)

这种进程间通信不仅非常低效;它也无效。信号没有排队;他们要么待定也要等待(*)。因此,除非接收方进程在发送方发送另一个信号之前读取信号,否则信号将丢失。

如果你真的想做一些像这样可怕的事情,收件人需要通过向发送方发送信号来确认收到的每个信号,并且发送方需要等待发送下一个信号,直到确认上一个信号为止。

(*)实际上,实时信号已排队,但队列的深度有一个限制,并确保它不会溢出将需要痛苦和脆弱的实时优先级管理逻辑。