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 回答