您的位置:首页 > 其它

信号的自我理解(不知对错)

2014-04-30 18:24 344 查看
#include
#include
#include
#include

static void
sig_handler( int signo )
{
printf( "getsignal\n" );
}

int
main( void )
{
sigset_t    newmask,zeromask;
pid_t      pid;

sigemptyset(&zeromask );
sigemptyset(&newmask );
sigaddset(&newmask, SIGUSR1 );
sigprocmask(SIG_BLOCK, &newmask, NULL);      //1
signal(SIGUSR1, sig_handler );

if( (pid =fork()) == 0 )
{
sleep( 2 );
printf( "child\n" );
sigsuspend( &zeromask );
printf( "child done\n" );
exit( 0 );
}
printf("%d\n", pid );
printf("father\n" );
kill( pid,SIGUSR1 );
printf("father done\n" );

exit( 0);
}


如果省略1,则输出中子进程无child done。

添加上则有。

进程间的信号传递要用sigprocmask来阻塞(保留)信号,不然可能在sigsuspend之前传递的信号就已捕获,sigsuspend就无法返回。

#include
#include
#include
#include

static void
sig_handler( int signo )
{
printf( "getsignal\n" );
}

int
main( void )
{
sigset_t    newmask,zeromask;
pid_t       pid;

sigemptyset(&zeromask );
sigemptyset(&newmask );
sigaddset(&newmask, SIGUSR1 );
signal(SIGUSR1, sig_handler );

if( (pid =fork()) == 0 )
{
printf("child\n" );
sigsuspend(&zeromask );
printf("child done\n" );
exit( 0);
}
sleep( 2);
printf("father\n" );
kill( pid,SIGUSR1 );
sleep( 2);
printf("father done\n" );

exit( 0);
}


虽然用sleep可能不太适合(负载重时可能超过sleep2的时间),但忽略子进程被阻塞等延迟情况。

以上程序的输出为

child

father

get signal

child done

father done

1、程序执行,因主进程中sleep(2),执行进程切换至子进程

2、子进程输出child,并挂起,从而执行进程恢复为主进程

3、主进程如sleep(2)执行结束则输出father,并向子进程发送信号,然后子进程sleep(2),执行切换至子进程

4、一进入子进程即捕获主进程发送的信号,输出getsignal,并从挂起退出输出 child done,子进程执行完毕

5、执行切换至主进程,sleep(2)执行结束后,输出father done,主进程执行结束。

主进程未调用kill发送信号时,执行子进程过程时没有获取到信号。

主进程在调用kill向子进程发送信号后,相对于主进程kill发送后,执行第一条子进程中的某一语句时,子进程即获取到信号。此时如子进程处在挂起状态,则退出挂起。

如果主进程的kill执行前,子进程已经进入pause状态,则在下一次切换到子进程时,子进程捕捉到信号并退出pause状态。

如果主进程的kill执行时,子进程还未进入pause状态,则在下一次切换到子进程时,子进程同样捕捉到信号,但是当执行到pause时,子进程便被挂起,如无信号再次传入,则无法退出挂起状态。

如果把上面程序的第一个sleep(2)去除,则程序可能会发生多种情况:

其中一种:主进程的kill发送信号后,切换至子进程时,子进程可能还没执行到sigsuspend。但此时信号已被捕获,并且sigsuspend没有能捕捉的信号,程序无childdone。

所以进程间的信号传输一般用屏蔽字阻塞,这样只有当执行sigsuspend时,此函数去除相应屏蔽字才能捕捉相应信号!(函数捕捉到信号从挂起返回时,恢复屏蔽字原值)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: