Bla*_*ary 6 c unix posix signals
我正在进行一项任务,该任务使用信号在两个进程之间传输二进制消息,目的是了解信号(这确实是一种奇怪的用法).
在我的程序中,两个进程传递代码,然后一个消息传递给另一个.SIGUSR1代表0,SIGUSR2代表1.想法是发送消息的进程将使用kill函数与任何SIGUSR来获取消息,接收进程将有一个信号处理程序来解释代码.
所以这就是问题所在.我有发件人启动.它在等待代码发送时休眠.接收方发送两个SIGINT来表示"密码",pidof(8)用于查找发送方的pid.
一旦发送者的信号处理程序读取了这些信号,识别出它是正确的密码,它就会继续发送消息.
接收器现在经历了一些功能,并且每秒钟都在等待通过中断传递每个位.问题是,这种情况从未发生过.
我已将其设置为发送方正在发送一个位(在这种情况下为0),如下所示:
kill(washingtonPID,SIGUSR1);
Run Code Online (Sandbox Code Playgroud)
其中washingtonPID是接收器的PID,我已经验证这是正确的PID.
接收者的处理程序如下所示:
//IN MAIN
signal(SIGINT,bitReceiver);
signal(SIGUSR1,bitReceiver);
signal(SIGUSR2,bitReceiver);
//OUTSIDE MAIN
void bitReceiver(int signum)
{
if(signum == SIGUSR1)
{
fprintf(stderr,"SIGUSR1 - 0");
bit = 0;
}
else if (signum == SIGUSR2)
{
fprintf(stderr,"SIGUSR2 - 1");
bit = 1;
}
else //sigint
raise(SIGINT);
return;
}
Run Code Online (Sandbox Code Playgroud)
其中bit是全局变量.它最初设置为-1.
这是读取位的函数:
int receiveBit()
{
while(bit == -1)
{
sleep(1);
}
fprintf(stderr,"%d",bit);
int bit2 = bit;
bit = -1;
return bit2;
}
Run Code Online (Sandbox Code Playgroud)
所以基本的运行是这样的:在代码从接收器发送到发送器之后,发送器开始向接收器发送USR1和USR2的终止信号,最终应该形成二进制消息.
接收器只是在这一点等待,每秒钟都在睡觉.当它被中断时,处理程序将位设置为0或1,将其踢出睡眠状态,打印该位并返回它.
如果我让两个程序正常运行,接收器就处于休眠状态,并且永远不会调用处理程序(即使我可以看到其他进程正在进行调用).
如果我停止发送器,并手动发送杀戮信号,我可以发送一个,也许两个信号,两者都正确处理.之后,我收到一条消息,如"用户信号2",打印到终端.这不是我的程序中的东西,程序立即停止.
任何关于为什么我的处理程序没有被使用的见解,以及为什么我不能手动发送超过一个或两个信号将非常感激.
谢谢你的时间.
编辑:似乎人们对此感到难过.有没有我可以尝试的调试技巧?
正如许多人已经评论过的那样,你根本不应该用信号做这件事.当它出错时(它会像它一样)试图找出未定义的行为背后的错误,即使不是不可能,也很难.
由于fprintf在同一个流上运行,因此在信号处理程序内使用非异步安全的系统调用(如fprintf)可能会破坏数据.与共享变量相同.
由于您使用的是linux,因此不会阻止相同类型的信号,这意味着快速传递相同的信号可能会导致对处理程序的递归调用.捕获到信号后,信号的处置将重置为SIG_DFL,并且需要再次在处理程序中重新建立(如果在重新建立更改之前传送信号,也可能会失败).
这就是为什么你可以在信号重置为默认值之前发送最多1个相同类型的信号,并用"用户信号xx"终止程序.
我建议你不要用代码来折磨自己,拿一些教科书或教程,然后试着去做.
如果它发生,也应该避免信号呼叫.从手册页:
signal()的行为在UNIX版本中各不相同,并且在不同版本的Linux上也有不同的历史变化. 避免使用:改为使用sigaction(2).
| 归档时间: |
|
| 查看次数: |
7939 次 |
| 最近记录: |