Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sys/signal.h>
- #include <stdio.h>
- #include <cstdlib>
- #include <sys/types.h>
- #include <unistd.h>
- #include <string.h>
- #include <errno.h>
- #include <wait.h>
- #include <time.h>
- const char N = 100;
- void child1();
- void child2();
- void child3();
- void child4();
- void child5();
- void child6();
- void child7();
- void child8();
- gid_t list[100];
- pid_t pid[9] = {}, temp_pid;
- char *program_name, count = 0;
- time_t timer, temp_time;
- struct sigaction act_term, act_usr1, act_usr2;
- sigset_t mask;
- union sigval value;
- char send_pid_count = 0;
- void printe() {
- fprintf(stderr, "%s: %s", program_name, strerror(errno));
- errno = 0;
- }
- char number() {
- for (int i = 0; i < 9; ++i)
- if (getpid() == pid[i])
- return i;
- }
- void handle_termination(int signum) {
- char process_number = number();
- fprintf(stdout, "%d pid=%d ppid=%d завершил работу после %d-го сигнала USR1\n",
- process_number, getpid(), getppid(), count);
- exit(0);
- }
- void send_pid(int signum, siginfo_t *siginfo, void *context) {
- send_pid_count++;
- printf("%d %d\n", siginfo->si_value. sival_int, siginfo->si_pid);
- pid[siginfo->si_value.sival_int] = siginfo->si_pid;
- }
- void handle_signal(int signum) {
- time(&temp_time);
- char process_number = number();
- if (process_number == 1) return;
- ++count;
- fprintf(stdout, "%d pid=%d ppid=%d получил USR1 %lf %d\n",
- process_number, getpid(), getppid(), difftime(temp_time, timer), count);
- if (process_number == 5) {
- fprintf(stdout, "%d pid=%d ppid=%d послал USR1 %lf %d\n",
- process_number, getpid(), getppid(), difftime(temp_time, timer), count);
- killpg(pid[6], SIGUSR1);
- }
- if (process_number == 8)
- kill(pid[1], SIGUSR1);
- }
- void child1() {
- pid[1] = getpid();
- printf("1 - %d\n", getpid());
- sigaction(SIGTERM, &act_term, 0);
- sigaction(SIGUSR1, &act_usr1, 0);
- sigaction(SIGUSR2, &act_usr2, 0);
- switch (pid[2] = fork()) {
- case -1: printe(); break;
- case 0: child2(); break;
- default: ;
- switch (pid[5] = fork()) {
- case -1: printe(); break;
- case 0: child5(); break;
- default: ;
- switch (pid[4] = fork()) {
- case -1: printe(); break;
- case 0: child4(); break;
- default: ;
- switch (pid[3] = fork()) {
- case -1: printe(); break;
- case 0: child3(); break;
- default: ;
- }
- }
- }
- }
- while (send_pid_count != 3) pause();
- setpgid(pid[2], pid[2]);
- setpgid(pid[3], pid[2]);
- setpgid(pid[4], pid[2]);
- setpgid(pid[5], pid[2]);
- while (count < N) {
- fprintf(stdout, "1 pid=%d ppid=%d послал USR1 %lf\n",
- getpid(), getppid(), 0);
- killpg(pid[2], SIGUSR1);
- pause();
- usleep(100);
- ++count;
- }
- sleep(3);
- fprintf(stdout, "1 pid=%d ppid=%d послал SIGTERM %lf\n",
- getpid(), getppid(), 0);
- killpg(pid[6], SIGTERM);
- setpgid(pid[1], pid[1]);
- setpgid(pid[2], pid[1]);
- setpgid(pid[3], pid[1]);
- setpgid(pid[4], pid[1]);
- setpgid(pid[5], pid[1]);
- setpgid(pid[8], pid[1]); //----------------------pid[6, 7, 8] не относит к группе pid[1]
- setpgid(pid[6], pid[1]); //----------------------pid[6, 7, 8] не относит к группе pid[1]
- setpgid(pid[7], pid[1]); //----------------------pid[6, 7, 8] не относит к группе pid[1]
- sleep(1);
- for (int i = 0; i < 9; ++i)
- printf("%d group=%d\n", pid[i], getpgid(pid[i]));
- printf("\n");
- killpg(pid[1], SIGTERM);
- killpg(pid[6], SIGTERM);
- }
- void child2() {
- printf("2 - %d\n", getpid());
- pid[2] = getpid();
- while (1) pause();
- }
- void child3() {
- printf("3 - %d\n", getpid());
- pid[3] = getpid();
- while (1) pause();
- }
- void child5() {
- printf("5 - %d\n", getpid());
- pid[5] = getpid();
- switch (pid[6] = fork()) {
- case -1: printe(); break;
- case 0: child6(); break;
- default: ;
- usleep(100);
- switch (pid[7] = fork()) {
- case -1: printe(); break;
- case 0: child7(); break;
- default: ;
- usleep(100);
- switch (pid[8] = fork()) {
- case -1: printe(); break;
- case 0: child8(); break;
- default: ;
- }
- }
- }
- setpgid(pid[6], pid[6]);
- setpgid(pid[7], pid[6]);
- setpgid(pid[8], pid[6]);
- while (1) pause();
- }
- void child4() {
- printf("4 - %d\n", getpid());
- pid[4] = getpid();
- while (1) pause();
- }
- void child6() {
- printf("6 - %d\n", getpid());
- pid[6] = getpid();
- value.sival_int = 6;
- sigqueue(pid[1], SIGUSR2, value);
- while (1) pause();
- }
- void child7() {
- printf("7 - %d\n", getpid());
- pid[7] = getpid();
- value.sival_int = 7;
- sigqueue(pid[1], SIGUSR2, value);
- while (1) pause();
- }
- void child8() {
- printf("8 - %d\n", getpid());
- pid[8] = getpid();
- value.sival_int = 8;
- sigqueue(pid[1], SIGUSR2, value);
- while (1) pause();
- }
- int main(int argc, char *argv[], char *env[]) {
- printf("0 - %d\n", getpid());
- sigemptyset(&mask);
- act_term.sa_mask = mask;
- act_term.sa_handler = handle_termination;
- act_usr1.sa_mask = mask;
- act_usr1.sa_handler = handle_signal;
- act_usr1.sa_flags = SA_RESTART;
- act_usr2.sa_mask = mask;
- act_usr2.sa_sigaction = send_pid;
- act_usr2.sa_flags = SA_SIGINFO;
- program_name = argv[0];
- switch (pid[0] = fork()) {
- case -1: printe(); break;
- case 0: child1(); break;
- default: ;
- }
- waitpid(-1, NULL, 0);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement