學習信號處理的一個例子

在學習<<UNIX程序設計>>的中信號處理的時候,我把書上的例子給寫出來,並寫出了一些自己的一些疑問:

1. 在第95行的時候,書上使用的是while(sigflag == 0),我想是不是使用if(sigflag == 0)是否也可以。

2.如果信號的動作是終止進程,則sigsuspend函數不返回。如果信號是動作的執行信號句柄,則在信號句柄返回後,sigsuspend函數返回。

代碼如下:

  1. #include <signal.h>
  2. #include <iostream.h>
  3. #include <stdio.h>
  4. #include <sys/wait.h>
  5. static volatile sig_atomic_t sigflag;
  6. static sigset_t newmask,oldmask,zeromask;
  7. static void sig_usr(int);
  8. static void output(char*);
  9. static void WAIT_PARENT(void);
  10. static void TELL_WAIT(void);
  11. static void TELL_CHILD(pid_t);
  12. void pr_exit(int status)
  13. {
  14.     int sig;
  15.     if(WIFEXITED(status))
  16.      cout<<"normal termination, exit status:"<<WEXITSTATUS(status)<<endl;
  17.     else if(WIFSIGNALED(status))
  18.     {
  19.         sig = WTERMSIG(status);
  20. #ifdef WCOREDUMP
  21.     cout<<"abnormal termination,signal number:"<<sig<<WCOREDUMP(status)?"(core file generated)":"";
  22. #else
  23.     cout<<"abnormal termination,signal number:"<<sig;
  24. #endif
  25.     }
  26.     else if(WIFSTOPPED(status))
  27.     {
  28.        sig = WSTOPSIG(status);
  29.        cout<<"child stopped,signal number:"<<sig<<endl;
  30.        psignal(sig,"");
  31.     }   
  32. }
  33. #define MYSYNOPT 1
  34. int main(void)
  35. {
  36.     pid_t pid;
  37. #ifdef MYSYNOPT
  38.     TELL_WAIT();
  39. #endif
  40.     if((pid = fork()) < 0)
  41.       cout<<"fork error"<<endl;
  42.     else if(pid == 0)
  43.     {
  44. #ifdef MYSYNOPT
  45.         WAIT_PARENT();
  46. #endif
  47.     output("output from child/n");
  48.     return 2;
  49.     }
  50.     else
  51.     {
  52.         output("output from parent/n");
  53. #ifdef MYSYNOPT
  54.     TELL_CHILD(pid);
  55. #endif
  56.     int status;
  57.     waitpid(pid,&status,0);
  58.     pr_exit(status);
  59.     }
  60.     return 1;
  61. }
  62. static void output(char* str)
  63. {
  64.     char * ptr;
  65.     int c;
  66.     setbuf(stdout,NULL); 
  67.     for( ptr = str; c = *ptr++;)
  68.     {
  69.        sleep(1);        
  70.        putc(c,stdout);
  71.     }
  72. }
  73. static void sig_usr(int signo)
  74. {
  75.     sigflag = 1;
  76.     return ;
  77. }
  78. void TELL_WAIT(void)
  79. {
  80.     if(signal(SIGUSR1,sig_usr) == SIG_ERR)
  81.     {
  82.         cout<<"signal(SIGUSR1)error"<<endl;
  83.     return ;
  84.     }
  85.     sigemptyset(&zeromask);
  86.     sigemptyset(&newmask);
  87.     sigaddset(&newmask,SIGUSR1);
  88.     if(sigprocmask(SIG_BLOCK,&newmask,&oldmask) < 0)
  89.     {
  90.        cout<<"SIG_BLOCK_ERROR/n"<<endl;
  91.     }
  92. }
  93. void WAIT_PARENT(void)
  94. {
  95.   if(sigflag == 0)
  96.   {
  97.      cout<<"before sigsuspend()"<<endl;   
  98.      sigsuspend(&zeromask);
  99.      cout<<"after sigsuspend()"<<endl;
  100.   }
  101. sigflag = 0;
  102. if(sigprocmask(SIG_SETMASK,&oldmask,NULL)<0)
  103.    cout<<"SIG_SETMASK error"<<endl;
  104. }
  105. void TELL_CHILD(pid_t pid)
  106. {
  107.     kill(pid,SIGUSR1);
  108. }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章