Advertisement
Guest User

Untitled

a guest
Nov 19th, 2017
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.29 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/wait.h>
  4. #include <unistd.h>
  5. #include <errno.h>
  6. #include <string.h>
  7. #include <time.h>
  8.  
  9. #define ERR(source) (fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
  10.                      perror(source),kill(0,SIGKILL),\
  11.                          exit(EXIT_FAILURE))
  12.  
  13. volatile sig_atomic_t last_signal = 0;
  14. int count_rec = 0;
  15.  
  16. void sethandler( void (*f)(int), int sigNo) {
  17.     struct sigaction act;
  18.     memset(&act, 0, sizeof(struct sigaction));
  19.     act.sa_handler = f;
  20.     if (-1==sigaction(sigNo, &act, NULL)) ERR("sigaction");
  21. }
  22.  
  23. void sig_handler(int sig) {
  24.     last_signal = sig;
  25. }
  26.  
  27. void sigusr2_handler(int sig){
  28.     last_signal = sig;
  29.     count_rec++;
  30.  
  31. }
  32.  
  33. void sigchld_handler(int sig) {
  34.     pid_t pid;
  35.     for(;;){
  36.         pid=waitpid(0, NULL, WNOHANG);
  37.         if(pid==0) return;
  38.         if(pid<=0) {
  39.             if(errno==ECHILD) return;
  40.             ERR("waitpid");
  41.         }
  42.     }
  43. }
  44.  
  45. void child_work( int m, int p){
  46.  
  47.     int count = 0;
  48.     struct timespec t = {0, m*10000};
  49.     while(1){
  50.         for(int i=0; i<p; i++){
  51.             nanosleep(&t,NULL);        
  52.             if(kill(getppid(),SIGUSR1)) ERR("kill");   
  53.             }
  54.  
  55.     if(kill(getppid(),SIGUSR2)) ERR("kill");
  56.     count++;
  57.     printf("[%d] sent %d SIGUSR2\n", getpid(), count);
  58.     }
  59.  
  60.  
  61.  
  62.  
  63. }
  64.  
  65.  
  66. void usage(char *name){
  67.     fprintf(stderr,"USAGE: %s m  p\n",name);
  68.     fprintf(stderr,"m - number of 1/1000 milliseconds between signals [1,999], i.e. one milisecond maximum\n");
  69.     fprintf(stderr,"p - after p SIGUSR1 send one SIGUSER2  [1,999]\n");
  70.     exit(EXIT_FAILURE);
  71. }
  72.  
  73. void parent_work(sigset_t oldmask){
  74.  
  75.     while(1){
  76.  
  77.         last_signal=0;
  78.         while(last_signal!=SIGUSR2){
  79.             sigsuspend(&oldmask);
  80.             }
  81.        
  82.         printf("[PARENT] received %d SIGURS\n", count_rec);
  83.         }
  84.  
  85.  
  86. }
  87.  
  88.  
  89. int main(int argc, char**argv) {
  90.  
  91. int m,p;
  92. if(argc!=3) usage(argv[0]);
  93.  
  94. m = atoi(argv[1]);
  95. p = atoi(argv[2]);
  96. if(m<=0 || m>999 || p <=0 || p>999) usage(argv[0]);
  97.  
  98. sethandler(sigchld_handler,SIGCHLD);
  99. sethandler(sig_handler,SIGUSR1);
  100. sethandler(sigusr2_handler,SIGUSR2);
  101.  
  102. sigset_t mask,omask;
  103. sigemptyset(&mask);
  104. sigaddset(&mask,SIGUSR1);
  105. sigaddset(&mask,SIGUSR2);
  106. sigprocmask(SIG_BLOCK, &mask, &omask);
  107.  
  108. pid_t pid;
  109. if((pid=fork())<0) ERR("fork");
  110.  
  111.  
  112. if(pid == 0){
  113.     child_work(m,p);
  114. }
  115. else{
  116.  
  117.     parent_work(omask);
  118.     while(wait(NULL)>0);
  119. }
  120.  
  121. sigprocmask(SIG_UNBLOCK,&mask,NULL);
  122. return (EXIT_SUCCESS);
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement