如何让两个进程连续发出信号?

时间:2016-05-28 09:36:01

标签: c linux process signals

我想模拟一个应该与父母一起连续发送和接收信号的游戏服务器。方案如下:

  • 家长向游戏发送信号。
  • 游戏捕获信号并向父母发送信号。
  • 父母捕获信号并再次向游戏发送信号。

依旧......

问题是第一圈后停止接收或发送:

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();
    }
}

为什么它停在这里?游戏服务器不应该抓住父母的信号并再次打印“游戏”......

2 个答案:

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

来自Linux' man 2 sigaction

  

<强> SA_NODEFER

     

不要阻止从自己的信号处理程序中接收信号。只有在建立信号处理程序时,此标志才有意义。

POSIX words this differently

  

SA_NODEFER

     

如果设置并且 sig 被捕获, sig 将不会被添加到                        进入信号处理程序时线程的信号掩码                        除非它包含在 sa_mask 中。否则, sig 应该                        在进入时总是被添加到线程的信号掩码中                        信号处理程序。

请注意每个信号处理程序在每次调用时都会获得它自己的堆栈,因此这个递归乒乓球迟早会在内存不足的情况下结束。

答案 1 :(得分:0)

使用消息队列或共享内存来执行此操作。如上所述,这最终会耗尽内存并且会崩溃。