测试一些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。
答案 0 :(得分:7)
这种进程间通信不仅非常低效;它也无效。信号没有排队;他们要么待定也要等待(*)。因此,除非接收方进程在发送方发送另一个信号之前读取信号,否则信号将丢失。
如果你真的想做一些像这样可怕的事情,收件人需要通过向发送方发送信号来确认收到的每个信号,并且发送方需要等待发送下一个信号,直到确认上一个信号为止。
(*)实际上,实时信号已排队,但队列的深度有一个限制,并确保它不会溢出将需要痛苦和脆弱的实时优先级管理逻辑。