View difference between Paste ID: TJHGbc9m and 5vbbSg7c
SHOW: | | - or go back to the newest paste.
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-
      sleep(1);
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]);
121+
   setpgid(pid[6], pid[1]); //----------------------pid[6, 7, 8] не относит к группе pid[1]
122-
   setpgid(pid[7], 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
}