我想模拟一个应该与父母一起连续发送和接收信号的游戏服务器。方案如下:
依旧......
问题是第一圈后停止接收或发送:
imap_rfc822_parse_headers(imap_fetchheader($this->get_imap_stream(), $mail_id, FT_UID));
输出如下:
static int game_s;
void game()
{
printf("game\n");
signal(SIGUSR1,game);
sleep(1);
kill(getppid(),SIGUSR1);
pause();
}
void parent()
{
printf("parent\n");
signal(SIGUSR1,parent);
sleep(1);
kill(game_s,SIGUSR1);
pause();
}
void main()
{
game_s = fork();
if(game_s>0)
{
signal(SIGUSR1,parent);
sleep(1);
kill(game_s,SIGUSR1);
pause();
}
else
{
signal(SIGUSR1,game);
pause();
}
}
为什么它停在这里?游戏服务器不应该抓住父母的信号并再次打印“游戏”......
答案 0 :(得分:2)
默认情况下,特定信号的接收在进程收到此特定信号之前被阻止,直到相关信号处理程序被丢弃为止。
来自man 3 signal
:
void (*signal(int sig, void (*func)(int)))(int);
[...]
当一个信号出现,并且func指向一个函数时,它是实现定义的是否相当于:
signal(sig, SIG_DFL);
被执行或者实现阻止一些实现定义的信号集(至少包括sig)发生,直到当前信号处理完成。
要更改此行为,请通过sigaction()
而非signal()
建立信号处理(出于可移植性原因,应采取任何方式)。
sigaction()
需要struct sigaction
。后者的成员sa_flags
应设置SA_NODEFER
。
<强> SA_NODEFER 强>
不要阻止从自己的信号处理程序中接收信号。只有在建立信号处理程序时,此标志才有意义。
SA_NODEFER
如果设置并且 sig 被捕获, sig 将不会被添加到 进入信号处理程序时线程的信号掩码 除非它包含在 sa_mask 中。否则, sig 应该 在进入时总是被添加到线程的信号掩码中 信号处理程序。
请注意每个信号处理程序在每次调用时都会获得它自己的堆栈,因此这个递归乒乓球迟早会在内存不足的情况下结束。
答案 1 :(得分:0)
使用消息队列或共享内存来执行此操作。如上所述,这最终会耗尽内存并且会崩溃。