首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

一个关于apue里的有关问题

2014-01-17 
一个关于apue里的问题最近在看unix编程,看到了信号这一章,好迷惑。。。。很多都不能理解。比如在下面这段代码中

一个关于apue里的问题
   最近在看unix编程,看到了信号这一章,好迷惑。。。。很多都不能理解。比如在下面这段代码中TELL_WAIT()为什么要Block SIGUSR1 and SIGUSR2 呢?如果没有阻塞这两个信号有什么后果呢?望各位路过大神可以解答一下我的疑惑。万分感激    

#include "apue.h"

static volatile sig_atomic_t sigflag; /* set nonzero by sig handler */
static sigset_t newmask, oldmask, zeromask;

static void
sig_usr(int signo)      /* one signal handler for SIGUSR1 and SIGUSR2 */
{
        sigflag = 1;
}

void
TELL_WAIT(void)
{
        if (signal(SIGUSR1, sig_usr) == SIG_ERR)
                err_sys("signal(SIGUSR1) error");
        if (signal(SIGUSR2, sig_usr) == SIG_ERR)
                err_sys("signal(SIGUSR2) error");
        sigemptyset(&zeromask);
        sigemptyset(&newmask);
        sigaddset(&newmask, SIGUSR1);
        sigaddset(&newmask, SIGUSR2);
/*                                                    
         * Block SIGUSR1 and SIGUSR2, and save current signal mask.
         */                                                   
        if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)   
                err_sys("SIG_BLOCK error");                   
}                                                             
                                                              
void                                                          
TELL_PARENT(pid_t pid)                                        
{                                                             
        kill(pid, SIGUSR2);             /* tell parent we're done */        
}                                                             
                                                              
void                                                          
WAIT_PARENT(void)                                             


{                                                             
        while (sigflag == 0)                                  
                sigsuspend(&zeromask);  /* and wait for parent */
  sigflag = 0;                                          
                                                              
        /*                                                    
         * Reset signal mask to original value.               
         */                                                   
        if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)     
                err_sys("SIG_SETMASK error");                 
}                                                             
                                                              
void                                                          
TELL_CHILD(pid_t pid)                                         
{                                                             
        kill(pid, SIGUSR1);                     /* tell child we're done */ 
}                                                             
                                                              
void                                                          
WAIT_CHILD(void)                                              


{                                                             
        while (sigflag == 0)                                  
                sigsuspend(&zeromask);  /* and wait for child */
        sigflag = 0;   
  /*                                                    
         * Reset signal mask to original value.               
         */                                                   
        if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)     
                err_sys("SIG_SETMASK error");                 
}               


                      linux?? apue
[解决办法]
你这个没有main函数没法说具体会出现什么结果。
阻塞信号是因为并发。比如说,多进程并发,三个信号同时响应,都打开一个文件将里面的数字加1,第一个信号打开取数+1还没有存回去,可能第二个进程就取数了,也取到了1,这样都是把2存回去了,加了两次按理说本来应该是三。这就是多个进程竞争冲突,所以一个信号操作的时候一般把别的信号block住,让此时只能响应一个信号
[解决办法]
正好手头有这本书,谈一谈我当初看的时候对这个问题的理解。
1.这段代码要参考程序清单8-7来看,(可能出版社不同具体标识也不同)
2.再请lz注意一下10.4节中的一句话:信号有可能丢失,一个信号发生了,进程却不知道这一点。有时用户希望通知内核阻塞一个信号,不要忽略该信号,在其发生时记住它,然后在进程做好准备时再通知他
好了,有了以上两点,我们分析一下这个例程,
假设fork之后(8-7程序)父进程先执行,那么它会TELL_CHILD,也就是把SIGUSR1发送给子进程,但是这个时候子进程根本就没有运行,也就是说子进程根本就没有准备好(参考上述第2点),可能会弄丢这个信号,所以需要阻塞这个SIGUSR1,等到子进程真正准备好了的时候(我的理解就是子进程运行起来的时候)在把这个阻塞的信号传递给它,所以子进程就能从sigsuspend中返回并继续执行

呵呵,个人理解,欢迎楼主批评指正

热点排行