Я пытаюсь понять, как работают сигналы блокировки и разблокировки, и я пытаюсь понять следующий фрагмент кода.В частности, я смотрю на строку 28 (прокомментированную в коде): int a = sigprocmask(SIG_UNBLOCK, &mask, NULL);
, то есть где сигнал разблокирован у ребенка.
В учебнике, из которого я получил код, написано, что код использует блокировку сигнала в порядкечтобы программа выполняла функцию добавления (упрощенно до printf("adding %d\n", pid);
) перед функцией удаления (упрощенно до printf("deleting %d\n", pid);
).Это имеет смысл для меня;блокируя сигнал SIGCHLD
, а затем разблокируя его после выполнения функции добавления, мы гарантируем, что обработчик не будет вызван, пока мы не выполним функцию добавления.Однако зачем нам разблокировать сигнал у ребенка?Разве это не устраняет всего смысла блокирования, сразу же разблокируя его, позволяя дочернему элементу удалить до того, как родитель добавит?
Однако вывод (описанный после кода) идентичен независимо от того, есть ли у менястрока закомментирована или нет, это означает, что это явно не то, что происходит.В учебнике говорится:
«Обратите внимание, что дети наследуют заблокированный набор своих родителей, поэтому мы должны быть осторожны, чтобы разблокировать сигнал SIGCHLD
в ребенке, прежде чем вызвать execve
».
Но мне все еще кажется, что разблокировка привела бы к вызову обработчика.Что именно делает эта линия?
void handler(int sig) {
pid_t pid;
printf("here\n");
while ((pid = waitpid(-1, NULL, 0)) > 0); /* Reap a zombie child */
printf("deleting %d\n", pid); /* Delete the child from the job list */
}
int main(int argc, char **argv) {
int pid;
sigset_t mask;
signal(SIGCHLD, handler);
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
sigprocmask(SIG_BLOCK, &mask, NULL); /* Block SIGCHLD */
pid = fork();
if (pid == 0) {
printf("in child\n");
int a = sigprocmask(SIG_UNBLOCK, &mask, NULL); // LINE 28
printf("a is %d\n",a);
execve("/bin/date", argv, NULL);
exit(0);
}
printf("adding %d\n", pid);/* Add the child to the job list */
sleep(5);
printf("awake\n");
int b = sigprocmask(SIG_UNBLOCK, &mask, NULL);
printf("b is %d\n", b);
sleep(3);
exit(0);
}
Выходы:
adding 652
in child
a is 0
Wed Apr 24 20:18:04 UTC 2019
awake
here
deleting -1
b is 0