Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <time.h>
- #include <signal.h>
- #include <sys/wait.h>
- #include <stdbool.h>
- #define PROC_COUNT 9 // общее кол-во процессов. Нулевой(исходный) + 8 дочерних
- static int processSelfNumber = 1; // номер выбранного на данный момент процесса
- static int USR1 = 0; // счетчик сигналов USR1
- static int USR2 = 0; // счетчик сигналов USR2
- static bool isTerminated = false;
- pid_t arrOfPIDs[PROC_COUNT] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; // массив для хранения процессов
- void printProcessInfo(const int signalValue)
- {
- printf("\t>> Процесс №%d (PID: %d, PPID: %d) получил сигнал %s за время %ld мксек\n\n", processSelfNumber, getpid(), getppid(), (signalValue == SIGUSR1) ? "SIGUSR1" : "SIGUSR2", clock());
- }
- void createGroup(const int parentIndex, const int firstProcessIndex, const int lastProcessIndex)
- {
- for (int i = firstProcessIndex; i <= lastProcessIndex; i++)
- setpgid(arrOfPIDs[i], arrOfPIDs[firstProcessIndex]);
- printf("\n\tБыла создана группа процессов %d..%d\n\n", firstProcessIndex, lastProcessIndex);
- }
- void sendSignalToProcess(const int processNumber, const int signalValue, const int signalCounter)
- {
- for (int h = 1; h <= signalCounter; h++)
- {
- kill(arrOfPIDs[processNumber], signalValue);
- printf("\tПроцесс №%d (PID: %d, PPID: %d) послал сигнал %s прцоессу №%d за время %ld >>\n\n", processSelfNumber, getpid(), getppid(), (signalValue == SIGUSR1) ? "SIGUSR1" : "SIGUSR2", processNumber, clock());
- usleep(100000);
- }
- kill(arrOfPIDs[processNumber], SIGTERM);
- }
- void sendSignalToGroup(const int groupMemberNumber, const int signalValue, const int signalCounter)
- {
- for (int h = 1; h <= signalCounter; h++)
- {
- killpg(arrOfPIDs[groupMemberNumber], signalValue);
- printf("\tПроцесс №%d (PID: %d, PPID: %d) послал сигнал %s группе %d за время %ld >>\n\n", processSelfNumber, getpid(), getppid(), (signalValue == SIGUSR1) ? "SIGUSR1" : "SIGUSR2", groupMemberNumber, clock());
- usleep(100000);
- }
- killpg(arrOfPIDs[groupMemberNumber], SIGTERM);
- }
- void signalHandler(const int signalValue)
- {
- usleep(clock());
- switch (signalValue)
- {
- case SIGUSR1:
- printProcessInfo(signalValue);
- USR1++;
- break;
- case SIGUSR2:
- printProcessInfo(signalValue);
- USR2++;
- break;
- default:
- printf("\t>> Процесс №%d (PID: %d, PPID: %d) получил сигнал SIGTERM за время %ld мксек\n\n", processSelfNumber, getpid(), getppid(), clock());
- isTerminated = true;
- break;
- }
- }
- void waitTillEnd()
- {
- for (int i = 0; i < PROC_COUNT; i++)
- wait(NULL);
- printf("\t\t\tПроцесс №%d (PID: %d, PPID: %d) закончил работу после %d-го сигнала SIGUSR1 и %d-го сигнала SIGUSR2\n\n", processSelfNumber, getpid(), getppid(), USR1, USR2);
- }
- void createProcess(const int childProcessNumber, pid_t pid)
- {
- pid = fork();
- if (pid == 0)
- {
- processSelfNumber = childProcessNumber;
- }
- if (pid > 0)
- arrOfPIDs[childProcessNumber] = pid;
- }
- void createProcessesTree(const int SIGNUM)
- {
- pid_t pid = fork(); // создание 0-го процесса
- if (pid == 0) // если процесс - дочерний
- {
- /*
- Дерево процессов
- 1->2
- 2->3
- 3->(4,5,6)
- 4->8
- 6->7
- */
- arrOfPIDs[processSelfNumber] = getpid();
- createProcess(2, pid);
- if (processSelfNumber == 2)
- {
- arrOfPIDs[processSelfNumber] = getpid();
- createProcess(3, pid);
- }
- if (processSelfNumber == 3)
- {
- arrOfPIDs[processSelfNumber] = getpid();
- for (int i = 4; i <= 6; i++)
- {
- pid = fork();
- if (pid == 0)
- {
- processSelfNumber = i;
- break;
- }
- if (pid > 0)
- arrOfPIDs[i] = pid;
- }
- }
- if (processSelfNumber == 4)
- {
- arrOfPIDs[processSelfNumber] = getpid();
- createProcess(8, pid);
- }
- if (processSelfNumber == 6)
- {
- arrOfPIDs[processSelfNumber] = getpid();
- createProcess(7, pid);
- }
- printf("\tПроцесс №%d (PID: %d, PPID: %d) создан\n", processSelfNumber, getpid(), getppid());
- usleep(100000);
- // создание группы процессов 3->(4-6)
- if (processSelfNumber == 3)
- {
- arrOfPIDs[processSelfNumber] = getpid();
- createGroup(3, 4, 6);
- }
- signal(SIGUSR1, signalHandler);
- signal(SIGUSR2, signalHandler);
- signal(SIGTERM, signalHandler);
- usleep(100000);
- /*
- последовательность обмена сигналами
- 1->(8,7,6)SIGUSR1
- 8->4 SIGUSR1
- 7->4 SIGUSR2
- 6->4 SIGUSR1
- 4->(3,2)SIGUSR1
- 2->1 SIGUSR2
- */
- switch (processSelfNumber)
- {
- case 1:
- sendSignalToGroup(6, SIGUSR1, SIGNUM);
- break;
- case 8:
- sendSignalToProcess(4, SIGUSR1, SIGNUM);
- break;
- case 7:
- sendSignalToProcess(4, SIGUSR2, SIGNUM);
- break;
- case 6:
- sendSignalToProcess(4, SIGUSR1, SIGNUM);
- break;
- case 4:
- sendSignalToGroup(2, SIGUSR1, SIGNUM);
- break;
- case 2:
- sendSignalToProcess(1, SIGUSR2, SIGNUM);
- break;
- }
- waitTillEnd();
- }
- else
- {
- printf("\n\t####### Процесс №0 (PID: %d, PPID: %d) #######\n\n", getpid(), getppid());
- wait(NULL);
- }
- }
- int main(int argc, char *argv[])
- {
- const int NUM_OF_ARGS = 2;
- if (argc < NUM_OF_ARGS)
- {
- fprintf(stderr, "Использование: %s <количество сигналов>\n", argv[0]);
- return EXIT_FAILURE;
- }
- createProcessesTree(atoi(argv[1]));
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement