Fixes in lab1
This commit is contained in:
parent
25b4284d09
commit
d037c502b1
47
lab1/questions.md
Normal file
47
lab1/questions.md
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
## Что такое процесс в контексте операционной системы? Чем процесс отличается от потока?
|
||||||
|
|
||||||
|
Изолированный набор ресурсов (потоков, страниц памяти, дескрипторов).
|
||||||
|
|
||||||
|
## Что такое системный вызов в контексте операционной системы?
|
||||||
|
|
||||||
|
Обращение к ядру.
|
||||||
|
|
||||||
|
## Что такое POSIX?
|
||||||
|
|
||||||
|
POSIX (англ. Portable Operating System Interface — переносимый интерфейс операционных систем) — набор стандартов,
|
||||||
|
описывающих интерфейсы между операционной системой и прикладной программой (системный API),
|
||||||
|
библиотеку языка C и набор приложений и их интерфейсов.
|
||||||
|
|
||||||
|
Стандарт создан для обеспечения совместимости различных UNIX-подобных операционных систем и переносимости
|
||||||
|
прикладных программ на уровне исходного кода, но может быть использован и для не-Unix систем.
|
||||||
|
|
||||||
|
## Какой системный вызов используется для создания нового процесса в Linux?
|
||||||
|
|
||||||
|
fork (57)
|
||||||
|
|
||||||
|
## Что такое идентификатор процесса (PID), и как его можно получить в программе на языке C?
|
||||||
|
|
||||||
|
Уникальное число, используемое для идентификации процесса.
|
||||||
|
|
||||||
|
```c
|
||||||
|
pid_t getpid(void);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Какой системный вызов позволяет родительскому процессу ожидать завершения своего потомка, и как он работает?
|
||||||
|
`waitpid` - переводит вызывающий поток в спящее состояние, до тех пор пока вызывающий процесс не получит `SIGCHLD` с соответствующим `PID`.
|
||||||
|
|
||||||
|
## Что произойдет, если родительский процесс завершится раньше своих потомков? Как это отразится на процессе потомков в операционной системе Linux?
|
||||||
|
Родителем потомков станет процесс с `PID=1`.
|
||||||
|
|
||||||
|
## Как можно программно контролировать завершение процесса в бесконечном цикле с вероятностью завершения 1/3?
|
||||||
|
|
||||||
|
## Что делает системный вызов waitpid() и как его использовать для управления процессами в отношениях «родитель-потомок»?
|
||||||
|
|
||||||
|
## Что происходит, если вызвать waitpid() с флагом WNOHANG, и чем это отличается от вызова без этого флага?
|
||||||
|
С флагом `WHOHANG` функция сразу вернёт значение, без флага заблокирует вызывающий поток до завершения запрошенного процесса.
|
||||||
|
|
||||||
|
## Как можно использовать системный вызов sleep() для организации пауз между выполнением операций в процессе?
|
||||||
|
|
||||||
|
## В чем отличие между системными вызовами fork() и exec(), и как они используются при работе с процессами?
|
||||||
|
|
||||||
|
## Как можно использовать команды ps или top для мониторинга состояния процессов в Linux и анализа их поведения?
|
@ -2,7 +2,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
// Global variable with data, needed to communicate with another process.
|
||||||
struct ping_pong_data_t {
|
struct ping_pong_data_t {
|
||||||
char const *name;
|
char const *name;
|
||||||
pid_t pid_to_print;
|
pid_t pid_to_print;
|
||||||
@ -10,32 +12,42 @@ struct ping_pong_data_t {
|
|||||||
double delay_seconds;
|
double delay_seconds;
|
||||||
} ping_pong_data;
|
} ping_pong_data;
|
||||||
|
|
||||||
|
// Signal handler for printing PID and sending signal back to another process.
|
||||||
void do_ping_pong(int signo) {
|
void do_ping_pong(int signo) {
|
||||||
if (signo != SIGUSR1)
|
if (signo != SIGUSR1) // Protecting from unexpected signals
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Printing some useful info
|
||||||
printf("[%s] Got signal\n", ping_pong_data.name);
|
printf("[%s] Got signal\n", ping_pong_data.name);
|
||||||
printf("[%s] Another side PID=%d\n", ping_pong_data.name, ping_pong_data.pid_to_print);
|
printf("[%s] Another side PID=%d\n", ping_pong_data.name, ping_pong_data.pid_to_print);
|
||||||
|
|
||||||
|
|
||||||
|
// Sleeping to avoid unreadable spam
|
||||||
printf("[%s] Sleeping %lf seconds before sending signal\n", ping_pong_data.name, ping_pong_data.delay_seconds);
|
printf("[%s] Sleeping %lf seconds before sending signal\n", ping_pong_data.name, ping_pong_data.delay_seconds);
|
||||||
usleep((useconds_t) (1000 * 1000 * ping_pong_data.delay_seconds));
|
usleep((useconds_t) (1000 * 1000 * ping_pong_data.delay_seconds));
|
||||||
|
|
||||||
|
// Sending signal back
|
||||||
printf("[%s] Sending signal\n", ping_pong_data.name);
|
printf("[%s] Sending signal\n", ping_pong_data.name);
|
||||||
kill(ping_pong_data.pid_to_send, SIGUSR1);
|
kill(ping_pong_data.pid_to_send, SIGUSR1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Global flag to stop infinite loop on interrupt (Ctrl+C)
|
||||||
volatile int is_running = 1;
|
volatile int is_running = 1;
|
||||||
|
|
||||||
|
|
||||||
|
// Interrupt (Ctrl+C) handler
|
||||||
void interrupt(int signo) {
|
void interrupt(int signo) {
|
||||||
if (signo != SIGINT)
|
if (signo != SIGINT) // Protecting from unexpected signals
|
||||||
return;
|
return;
|
||||||
|
kill(ping_pong_data.pid_to_send, SIGINT);
|
||||||
is_running = 0;
|
is_running = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Entry point
|
||||||
int main(void) {
|
int main(void) {
|
||||||
signal(SIGINT, interrupt);
|
// Obtaining PID of parent (main) process
|
||||||
|
|
||||||
pid_t parent_pid = getpid();
|
pid_t parent_pid = getpid();
|
||||||
|
// Obtaining PID of child (forked) process
|
||||||
pid_t child_pid = fork();
|
pid_t child_pid = fork();
|
||||||
|
|
||||||
|
|
||||||
@ -44,37 +56,62 @@ int main(void) {
|
|||||||
perror("Failed to fork\n");
|
perror("Failed to fork\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
case 0:
|
case 0:
|
||||||
|
// Obtaining PID of child (forked) process because fork() didn't return it
|
||||||
child_pid = getpid();
|
child_pid = getpid();
|
||||||
|
|
||||||
|
// Initializing settings
|
||||||
ping_pong_data.name = "\033[36mchild\033[0m";
|
ping_pong_data.name = "\033[36mchild\033[0m";
|
||||||
ping_pong_data.delay_seconds = 1.5;
|
ping_pong_data.delay_seconds = 1.5;
|
||||||
ping_pong_data.pid_to_print = parent_pid;
|
ping_pong_data.pid_to_print = parent_pid;
|
||||||
ping_pong_data.pid_to_send = parent_pid;
|
ping_pong_data.pid_to_send = parent_pid;
|
||||||
|
|
||||||
|
// Debug info printing
|
||||||
printf("[%s] My PID=%d\n", ping_pong_data.name, getpid());
|
printf("[%s] My PID=%d\n", ping_pong_data.name, getpid());
|
||||||
|
|
||||||
|
// Initializing interruption (Ctrl+C) handler
|
||||||
|
signal(SIGINT, interrupt);
|
||||||
|
|
||||||
|
// Initializing communication handler
|
||||||
signal(SIGUSR1, do_ping_pong);
|
signal(SIGUSR1, do_ping_pong);
|
||||||
|
|
||||||
break;
|
// Eventloop
|
||||||
|
while (is_running)
|
||||||
|
pause();
|
||||||
|
|
||||||
|
// Notification about execution finishing
|
||||||
|
printf("[%s] Interrupted\n", ping_pong_data.name);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
default:
|
default:
|
||||||
|
// Initializing settings
|
||||||
ping_pong_data.name = "\033[31mparent\033[0m";
|
ping_pong_data.name = "\033[31mparent\033[0m";
|
||||||
ping_pong_data.delay_seconds = 1.5;
|
ping_pong_data.delay_seconds = 1.5;
|
||||||
ping_pong_data.pid_to_print = child_pid;
|
ping_pong_data.pid_to_print = child_pid;
|
||||||
ping_pong_data.pid_to_send = child_pid;
|
ping_pong_data.pid_to_send = child_pid;
|
||||||
|
|
||||||
|
// Debug info printing
|
||||||
printf("[%s] My PID=%d\n", ping_pong_data.name, getpid());
|
printf("[%s] My PID=%d\n", ping_pong_data.name, getpid());
|
||||||
|
|
||||||
|
// Initializing interruption (Ctrl+C) handler
|
||||||
|
signal(SIGINT, interrupt);
|
||||||
|
|
||||||
|
// Initializing communication handler
|
||||||
signal(SIGUSR1, do_ping_pong);
|
signal(SIGUSR1, do_ping_pong);
|
||||||
|
|
||||||
|
// Sending initial signal to start communication chain
|
||||||
kill(parent_pid, SIGUSR1);
|
kill(parent_pid, SIGUSR1);
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Eventloop
|
||||||
while (is_running)
|
while (is_running)
|
||||||
pause();
|
pause();
|
||||||
|
|
||||||
|
// Notification about execution finishing
|
||||||
printf("[%s] Interrupted\n", ping_pong_data.name);
|
printf("[%s] Interrupted\n", ping_pong_data.name);
|
||||||
|
|
||||||
|
// Releasing zombie-process
|
||||||
|
waitpid(child_pid, NULL, 0);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user