Advertisement
Guest User

Untitled

a guest
Apr 12th, 2014
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <sys/signal.h>
  2. #include <stdio.h>
  3. #include <cstdlib>
  4. #include <sys/types.h>
  5. #include <unistd.h>
  6. #include <string.h>
  7. #include <errno.h>
  8. #include <wait.h>
  9. #include <time.h>
  10. const char N = 100;
  11. void child1();
  12. void child2();
  13. void child3();
  14. void child4();
  15. void child5();
  16. void child6();
  17. void child7();
  18. void child8();
  19. gid_t list[100];
  20. pid_t pid[9] = {}, temp_pid;
  21. char *program_name, count = 0;
  22. time_t timer, temp_time;
  23. struct sigaction act_term, act_usr1, act_usr2;
  24. sigset_t mask;
  25. union sigval value;
  26. char send_pid_count = 0;
  27.  
  28. void printe() {
  29.    fprintf(stderr, "%s: %s", program_name, strerror(errno));
  30.    errno = 0;
  31. }
  32.  
  33. char number() {
  34.    for (int i = 0; i < 9; ++i)
  35.       if (getpid() == pid[i])
  36.          return i;
  37. }
  38.  
  39. void handle_termination(int signum) {
  40.    char process_number = number();
  41.    fprintf(stdout, "%d pid=%d ppid=%d завершил работу после %d-го сигнала USR1\n",
  42.       process_number, getpid(), getppid(), count);
  43.    exit(0);
  44. }
  45.  
  46. void send_pid(int signum, siginfo_t *siginfo, void *context) {
  47.    send_pid_count++;
  48.    printf("%d %d\n", siginfo->si_value.   sival_int, siginfo->si_pid);
  49.    pid[siginfo->si_value.sival_int] = siginfo->si_pid;
  50. }
  51.  
  52. void handle_signal(int signum) {
  53.    time(&temp_time);
  54.    char process_number = number();
  55.    if (process_number == 1) return;
  56.    ++count;
  57.    fprintf(stdout, "%d pid=%d ppid=%d получил USR1 %lf %d\n",
  58.       process_number, getpid(), getppid(), difftime(temp_time, timer), count);
  59.  
  60.    if (process_number == 5) {
  61.       fprintf(stdout, "%d pid=%d ppid=%d послал  USR1 %lf %d\n",
  62.          process_number, getpid(), getppid(), difftime(temp_time, timer), count);
  63.       killpg(pid[6], SIGUSR1);
  64.    }
  65.    if (process_number == 8)
  66.       kill(pid[1], SIGUSR1);
  67. }
  68.  
  69. void child1() {
  70.    pid[1] = getpid();
  71.    printf("1 - %d\n", getpid());
  72.  
  73.    sigaction(SIGTERM, &act_term, 0);
  74.    sigaction(SIGUSR1, &act_usr1, 0);
  75.    sigaction(SIGUSR2, &act_usr2, 0);
  76.  
  77.    switch (pid[2] = fork()) {
  78.       case -1: printe(); break;
  79.       case  0: child2(); break;
  80.       default: ;
  81.          switch (pid[5] = fork()) {
  82.             case -1: printe(); break;
  83.             case  0: child5(); break;
  84.             default: ;
  85.                switch (pid[4] = fork()) {
  86.                   case -1: printe(); break;
  87.                   case  0: child4(); break;
  88.                   default: ;
  89.                      switch (pid[3] = fork()) {
  90.                         case -1: printe(); break;
  91.                         case  0: child3(); break;
  92.                         default: ;
  93.                      }
  94.                }
  95.          }
  96.    }
  97.    while (send_pid_count != 3) pause();
  98.    setpgid(pid[2], pid[2]);
  99.    setpgid(pid[3], pid[2]);
  100.    setpgid(pid[4], pid[2]);
  101.    setpgid(pid[5], pid[2]);
  102.  
  103.    while (count < N) {
  104.       fprintf(stdout, "1 pid=%d ppid=%d послал  USR1 %lf\n",
  105.           getpid(), getppid(), 0);
  106.       killpg(pid[2], SIGUSR1);
  107.       pause();
  108.       usleep(100);
  109.       ++count;
  110.    }
  111.    sleep(3);
  112.    fprintf(stdout, "1 pid=%d ppid=%d послал  SIGTERM %lf\n",
  113.       getpid(), getppid(), 0);
  114.    killpg(pid[6], SIGTERM);
  115.    setpgid(pid[1], pid[1]);  
  116.    setpgid(pid[2], pid[1]);
  117.    setpgid(pid[3], pid[1]);
  118.    setpgid(pid[4], pid[1]);
  119.    setpgid(pid[5], pid[1]);
  120.    setpgid(pid[8], pid[1]); //----------------------pid[6, 7, 8] не относит к группе pid[1]
  121.    setpgid(pid[6], pid[1]); //----------------------pid[6, 7, 8] не относит к группе pid[1]
  122.    setpgid(pid[7], pid[1]); //----------------------pid[6, 7, 8] не относит к группе pid[1]
  123.  
  124.    sleep(1);
  125.    for (int i = 0; i < 9; ++i)
  126.    printf("%d group=%d\n", pid[i], getpgid(pid[i]));
  127.    printf("\n");
  128.    killpg(pid[1], SIGTERM);
  129.    killpg(pid[6], SIGTERM);
  130. }
  131.  
  132. void child2() {
  133.    printf("2 - %d\n", getpid());
  134.    pid[2] = getpid();
  135.    while (1) pause();
  136. }
  137.  
  138. void child3() {
  139.    printf("3 - %d\n", getpid());
  140.    pid[3] = getpid();
  141.    while (1) pause();
  142. }
  143.  
  144. void child5() {
  145.    printf("5 - %d\n", getpid());
  146.    pid[5] = getpid();
  147.    switch (pid[6] = fork()) {
  148.       case -1: printe(); break;
  149.       case  0: child6(); break;
  150.       default: ;
  151.          usleep(100);
  152.          switch (pid[7] = fork()) {
  153.             case -1: printe(); break;
  154.             case  0: child7(); break;
  155.             default: ;
  156.                usleep(100);
  157.                switch (pid[8] = fork()) {
  158.                   case -1: printe(); break;
  159.                   case  0: child8(); break;
  160.                   default: ;
  161.                }
  162.          }
  163.    }
  164.    setpgid(pid[6], pid[6]);
  165.    setpgid(pid[7], pid[6]);
  166.    setpgid(pid[8], pid[6]);
  167.    while (1) pause();
  168. }
  169.  
  170. void child4() {
  171.    printf("4 - %d\n", getpid());
  172.    pid[4] = getpid();
  173.    while (1) pause();
  174. }
  175.  
  176. void child6() {
  177.    printf("6 - %d\n", getpid());
  178.    pid[6] = getpid();
  179.    value.sival_int = 6;
  180.    sigqueue(pid[1], SIGUSR2, value);
  181.    while (1) pause();
  182. }
  183.  
  184. void child7() {
  185.    printf("7 - %d\n", getpid());
  186.    pid[7] = getpid();
  187.    value.sival_int = 7;
  188.    sigqueue(pid[1], SIGUSR2, value);
  189.    while (1) pause();
  190. }
  191.  
  192. void child8() {
  193.    printf("8 - %d\n", getpid());
  194.    pid[8] = getpid();
  195.    value.sival_int = 8;
  196.    sigqueue(pid[1], SIGUSR2, value);
  197.    while (1) pause();
  198. }
  199.  
  200. int main(int argc, char *argv[], char *env[]) {
  201.    printf("0 - %d\n", getpid());
  202.  
  203.    sigemptyset(&mask);
  204.    act_term.sa_mask = mask;
  205.    act_term.sa_handler = handle_termination;
  206.  
  207.    act_usr1.sa_mask = mask;
  208.    act_usr1.sa_handler = handle_signal;
  209.    act_usr1.sa_flags = SA_RESTART;
  210.  
  211.    act_usr2.sa_mask = mask;
  212.    act_usr2.sa_sigaction = send_pid;
  213.    act_usr2.sa_flags = SA_SIGINFO;
  214.  
  215.  
  216.  
  217.    program_name = argv[0];
  218.    switch (pid[0] = fork()) {
  219.       case -1: printe(); break;
  220.       case  0: child1(); break;
  221.       default: ;
  222.    }
  223.    waitpid(-1, NULL, 0);
  224.    return 0;
  225. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement