Advertisement
Guest User

Untitled

a guest
Nov 15th, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.87 KB | None | 0 0
  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <sys/wait.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <unistd.h>
  8. #include <errno.h>
  9. #include <string.h>
  10. #include <time.h>
  11. #define ERR(source) (fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
  12.                      perror(source),kill(0,SIGKILL),\
  13.                          exit(EXIT_FAILURE))
  14.  
  15. volatile sig_atomic_t last_signal = 0;
  16. volatile sig_atomic_t sig_count = 0;
  17.  
  18. void sethandler( void (*f)(int), int sigNo) {
  19.     struct sigaction act;
  20.     memset(&act, 0, sizeof(struct sigaction));
  21.     act.sa_handler = f;
  22.     if (-1==sigaction(sigNo, &act, NULL)) ERR("sigaction");
  23. }
  24.  
  25. void sig_handler(int sig) {
  26.     last_signal = sig;
  27.     sig_count++;
  28.     printf("[%d] received %d SIGUSR1\n", getpid(), sig_count);
  29. }
  30.  
  31. ssize_t bulk_write(int fd, char *buf, size_t count){
  32.     ssize_t c;
  33.     ssize_t len=0;
  34.     do{
  35.         c=TEMP_FAILURE_RETRY(write(fd,buf,count));
  36.         if(c<0) return c;
  37.         buf+=c;
  38.         len+=c;
  39.         count-=c;
  40.     }while(count>0);
  41.     return len ;
  42. }
  43.  
  44. void parent_work() {
  45.     struct timespec t = {0, 10*1000000};
  46.     sethandler(SIG_IGN, SIGUSR1);
  47.     for (int i=0; i<100; i++){
  48.         nanosleep(&t,NULL);
  49.         if (kill(0, SIGUSR1)<0)ERR("kill");
  50.     }
  51.     printf("[PARENT] Terminates \n");
  52. }
  53.  
  54. void child_work(int i) {
  55.     int com=0;
  56.     struct timespec t = {2, 0};
  57.     struct timespec tt;
  58.    
  59.     /*for (int i=0; i<100; i++){
  60.         sigsuspend(&oldmask);
  61.         com++;
  62.         printf("[%d] received %d SIGUSR2\n", getpid(), com);
  63.        
  64.     }*/
  65.     //sethandler(sig_handler,SIGUSR1);
  66.     sleep(1);
  67.     int out;
  68.     ssize_t count;
  69.     srand(time(NULL)*getpid());
  70.     int s=10+rand()%(100-10+1);
  71.     printf("n=%d, s=%d\n", i, s);
  72.  
  73.    
  74.     char *buf=malloc(s*1024);
  75.     if(!buf) ERR("malloc");
  76.     memset(buf, i+'0', s*1024);
  77.     char name[15];
  78.     sprintf(name, "%d.TXT", getpid());
  79.     //printf("%s", name);
  80.     if((out=TEMP_FAILURE_RETRY(open(name,O_WRONLY|O_CREAT|O_TRUNC|O_APPEND,0777)))<0)ERR("open");
  81.     while(0!=nanosleep(&t,NULL))
  82.     {
  83.         while(0<sig_count-com)
  84.         {
  85.             if((count=bulk_write(out,buf,s))<0) ERR("write");
  86.             com++;
  87.         }
  88.     }
  89.     if(TEMP_FAILURE_RETRY(close(out)))ERR("close");
  90.     //printf("[%d] received %d SIGUSR1\n", getpid(), com);
  91. }
  92.  
  93. void create_children(int n, char** arg) {
  94.     pid_t s;
  95.     for (int i=1;i<n;i++) {
  96.         if((s=fork())<0) ERR("Fork:");
  97.         if(!s) {
  98.             sethandler(sig_handler,SIGUSR1);
  99.             child_work(atoi(arg[i]));
  100.             exit(EXIT_SUCCESS);
  101.         }
  102.     }
  103. }
  104.  
  105.  
  106. void usage(char *name){
  107.     fprintf(stderr,"USAGE: %s 0<n\n",name);
  108.     exit(EXIT_FAILURE);
  109. }
  110.  
  111. int main(int argc, char** argv) {
  112.     int n=argc-1;
  113.     if(argc<2)  usage(argv[0]);
  114.  
  115.     //sethandler(sig_handler,SIGUSR1);
  116.  
  117.     create_children(argc, argv);
  118.     parent_work();
  119.     while(n>0){
  120.         sleep(3);
  121.         pid_t pid;
  122.         for(;;){
  123.             pid=waitpid(0, NULL, WNOHANG);
  124.             if(pid>0) n--;
  125.             if(0==pid) break;
  126.             if(0>=pid) {
  127.                 if(ECHILD==errno) break;
  128.                 ERR("waitpid:");
  129.             }
  130.         }
  131.         printf("PARENT: %d processes remain\n",n);
  132.     }
  133.     return EXIT_SUCCESS;
  134. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement