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

#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时,此函数去除相应屏蔽字才能捕捉相应信号!(函数捕捉到信号从挂起返回时,恢复屏蔽字原值)

你可能感兴趣的:(信号的自我理解(不知对错))