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 | } |