日期:2014-05-16  浏览次数:20989 次

关于signal()函数
请求高手:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void waiting( ),stop( );
int wait_mark;
main( )
{
int p1,p2,stdout;
while((p1=fork( ))= =-1); /*创建子进程p1*/
if (p1>0)
{
while((p2=fork( ))= =-1); /*创建子进程p2*/
if(p2>0)
{
wait_mark=1;
signal(SIGINT,stop); /*接收到^c信号,转stop*/
waiting( );
kill(p1,SIGINT); /*向p1发软中断信号SIGINT*/
kill(p2,SIGINT); /*向p2发软中断信号SIGINT*/
wait(0); /*同步*/
wait(0);
printf("Parent process is killed!\n");
exit(0);
}
  else
  {
  wait_mark=1;
signal(SIGINT,stop); /*接收到软中断信号17,转stop*/
waiting( );
lockf(stdout,1,0);
printf("Child process 2 is killed by parent!\n");
lockf(stdout,0,0);
exit(0);
}
}
else
{
wait_mark=1;
signal(SIGINT,stop); /*接收到软中断信号16,转stop*/
waiting( );
lockf(stdout,1,0);
printf("Child process 1 is killed by parent!\n");
lockf(stdout,0,0);
exit(0);
}
}

void waiting( )
{
 while(wait_mark!=0);
}

void stop( )
{
wait_mark=0;
}
在这段程序的运行结果:
当你按下ctrl_c后,程序显示:
Child process 1 is killed by parent!
Child process 2 is killed by parent!
Parent process is killed!

mait_mark显然是为了同步的
但是小弟就有个问题不懂了
我们每次都是先把mait_mark=1然后再接信号
问题:
于是小弟就想了,要是进程在运行到signal(SIGINT,stop);时,信号没到,我们势必回在waiting()函数里面等待,而这个函数不是为了接收进程消息的,所以,我们从键盘上输入的任何的信息都是没有用的,也就是他是一个死循环了。
但是显然是不对的。

猜想:
那么就只有一个解释了,那就是signal()函数有同步机制,也就是说,signal(SIGINT,stop);函数必须要等到我们从键盘上输入数据时,才继续执行。那么,我们在程序中所作的同步机制起步是很多余。
为了验证这个想法,我将同步机制去掉后,结果让我相当失望,那就是你不必输入ctrl_c的消息,程序已经将上面的信息进行显示的。这就是说,signal()函数是无同步机制的。

于是,小弟就郁闷了,那么,我们上面的问题中所提出的问题是怎么解决的?signal()函数在实现的时候,是怎么做的。我们这样写
while(wait_mark!=1) signal(SIGINT,stop);
岂不是更好么

望各位高手帮忙解答
感激不尽


------解决方案--------------------
你的猜想是不对的,,

事实上p1,p2是两个子进程,你可以在waiting函数里面加打印语句,延迟父进程发信号的时间,你会发现是在不停的打印的
当你waiting的时候,,一旦有信号进入,是触发了你定义的信号处理函数,把wait_mark给修改了,
你得清楚signal(SIGINT,stop);的时候,你并没有调用stop函数,而是把一个函数指针给了一个回调函数的接口。。
只有在子进程接受到SIGINT信号的时候,系统查询你对这个信号的处理函数,才会调用stop函数
------解决方案--------------------
我是来学习学习的,希望以后大家多多指教