Основы операционных систем. Практикум

Тривиальная программа для иллюстрации понятий


/* Тривиальная программа для иллюстрации понятий группа процессов, сеанс, фоновая группа и т.д. */ #include <unistd.h> int main(void){ (void)fork(); while(1); return 0; }
Листинг 13-14.1. Тривиальная программа (13–14-1.c) для иллюстрации понятий группа процессов, сеанс, фоновая группа и т.д.
Закрыть окно





/* Программа, игнорирующая сигнал SIGINT */ #include <signal.h> int main(void){ /* Выставляем реакцию процесса на сигнал SIGINT на игнорирование */ (void)signal(SIGINT, SIG_IGN); /*Начиная с этого места, процесс будет игнорировать возникновение сигнала SIGINT */ while(1); return 0; }
Листинг 13-14.2. Программа (13–14-2.c), игнорирующая сигнал SIGINT.
Закрыть окно





/* Программа с пользовательской обработкой сигнала SIGINT */ #include <signal.h> #include <stdio.h> /* Функция my_handler – пользовательский обработчик сигнала */ void my_handler(int nsig){ printf("Receive signal %d, CTRL-C pressed\n", nsig); } int main(void){ /* Выставляем реакцию процесса на сигнал SIGINT */ (void)signal(SIGINT, my_handler); /*Начиная с этого места, процесс будет печатать сообщение о возникновении сигнала SIGINT */ while(1); return 0; }
Листинг 13-14.3. Программа (13–14-3.c) с пользовательской обработкой сигнала SIGINT.
Закрыть окно





/* Программа с пользовательской обработкой сигнала SIGINT, возвращающаяся к первоначальной реакции на этот сигнал после 5 его обработок*/ #include <signal.h> #include <stdio.h> int i=0; /* Счетчик числа обработок сигнала */ void (*p)(int); /* Указатель, в который будет занесен адрес предыдущего обработчика сигнала */ /* Функция my_handler – пользовательский обработчик сигнала */ void my_handler(int nsig){ printf("Receive signal %d, CTRL-C pressed\n", nsig); i = i+1; /* После 5-й обработки возвращаем первоначальную реакцию на сигнал */ if(i == 5) (void)signal(SIGINT, p); } int main(void){ /* Выставляем свою реакцию процесса на сигнал SIGINT, запоминая адрес предыдущего обработчика */ p = signal(SIGINT, my_handler); /*Начиная с этого места, процесс будет 5 раз печатать сообщение о возникновении сигнала SIGINT */ while(1); return 0; }
Листинг 13-14.4. Программа (13—14-4.c) с пользовательской обработкой сигнала SIGINT.
Закрыть окно





/* Программа с асинхронным получением информации о статусе двух завершившихся порожденных процессов */ #include <sys/types.h> #include <unistd.h> #include <waith> #include <signal.h> #include <stdio.h> /* Функция my_handler – обработчик сигнала SIGCHLD */ void my_handler(int nsig){ int status; pid_t pid; /* Опрашиваем статус завершившегося процесса и одновременно узнаем его идентификатор */ if((pid = waitpid(-1, &status, 0)) < 0){ /* Если возникла ошибка – сообщаем о ней и продолжаем работу */ printf("Some error on waitpid errno = %d\n", errno); } else { /* Иначе анализируем статус завершившегося процесса */ if ((status & 0xff) == 0) { /* Процесс завершился с явным или неявным вызовом функции exit() */ printf("Process %d was exited with status %d\n", pid, status >> 8); } else if ((status & 0xff00) == 0){ /* Процесс был завершен с помощью сигнала */ printf("Process %d killed by signal %d %s\n", pid, status &0x7f,(status & 0x80) ? "with core file" : "without core file"); } } } int main(void){ pid_t pid; /* Устанавливаем обработчик для сигнала SIGCHLD */ (void) signal(SIGCHLD, my_handler); /* Порождаем Сhild 1 */ if((pid = fork()) < 0){ printf("Can\'t fork child 1\n"); exit(1); } else if (pid == 0){ /* Child 1 – завершается с кодом 200 */ exit(200); } /* Продолжение процесса-родителя – порождаем Сhild 2 */ if((pid = fork()) < 0){ printf("Can\'t fork child 2\n"); exit(1); } else if (pid == 0){ /* Child 2 – циклится, необходимо удалять с помощью сигнала! */ while(1); } /* Продолжение процесса-родителя – уходим в цикл */ while(1); return 0; }
Листинг 13-14.5. Программа (13—14-5.c) с асинхронным получением информации о статусе двух завершившихся порожденных процессов.
Закрыть окно





/* Программа для иллюстрации ненадежности сигналов */ #include <sys/types.h> #include <unistd.h> #include <waith> #include <signal.h> #include <stdio.h> /* Функция my_handler – обработчик сигнала SIGCHLD */ void my_handler(int nsig){ int status; pid_t pid; /* Опрашиваем статус завершившегося процесса и одновременно узнаем его идентификатор */ if((pid = waitpid(-1, &status, 0)) < 0){ /* Если возникла ошибка – сообщаем о ней и продолжаем работу */ printf("Some error on waitpid errno = %d\n", errno); } else { /* Иначе анализируем статус завершившегося процесса */ if ((status & 0xff) == 0) { /* Процесс завершился с явным или неявным вызовом функции exit() */ printf("Process %d was exited with status %d\n", pid, status >> 8); } else if ((status & 0xff00) == 0){ /* Процесс был завершен с помощью сигнала */ printf("Process %d killed by signal %d %s\n", pid, status &0x7f,(status & 0x80) ? "with core file" : "without core file"); } } } int main(void){ pid_t pid; int i; /* Устанавливаем обработчик для сигнала SIGCHLD */ (void) signal(SIGCHLD, my_handler); /* В цикле порождаем 5 процессов-детей */ for (i=0; i if((pid = fork()) < 0){ printf("Can\'t fork child %d\n", i); exit(1); } else if (pid == 0){ /* Child i – завершается с кодом 200 + i */ exit(200 + i); } /* Продолжение процесса-родителя – уходим на новую итерацию */ } /* Продолжение процесса-родителя – уходим в цикл */ while(1); return 0; }
Листинг 13-14.6. Программа (13–14-6.c) для иллюстрации ненадежности сигналов.
Закрыть окно




Содержание раздела