fork () і як сигнали надходять до процесів


13

Я програму, яку я написав у C fork (), вийшов із дочірнього процесу. Жоден процес не припиниться. Якщо я запускаю програму з командного рядка і натискаю control-c, який процес (и) отримає сигнал переривання?

Відповіді:


20

Чому б ми не спробуємо це і подивитися? Ось тривіальна програма, яка використовує signal(3)для пастки SIGINTяк батьківського, так і дочірнього процесу та роздруковує повідомлення, що ідентифікує процес, коли він надходить.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void parent_trap(int sig) {fprintf(stderr, "They got back together!\n");}
void child_trap(int sig) {fprintf(stderr, "Caught signal in CHILD.\n");}
int main(int argc, char **argv) {
    if (!fork()) {
        signal(SIGINT, &child_trap);
        sleep(1000);
        exit(0);
    }
    signal(SIGINT, &parent_trap);
    sleep(1000);
    return 0;
}

Давайте назвемо це test.c. Тепер ми можемо це запустити:

$ gcc test.c
$ ./a.out
^CCaught signal in CHILD.
They got back together!

Сигнали переривань, що генеруються в терміналі, доставляються до активної групи процесів, до якої сюди входять і батьки, і дочірні . Ви бачите, що обидва child_trapі parent_trapбули страчені, коли я натискав Ctrl- C.

Існує тривале обговорення взаємодії між forkта сигналами в POSIX . Тут є найбільш матеріальною частиною цього:

Сигнал, що надсилається до групи процесів після вилки (), повинен бути доставлений і батькові, і дитині.

Вони також зазначають, що деякі системи можуть вести себе не зовсім правильно, зокрема, коли сигнал надходить дуже близько до часу fork(). Зрозуміти, чи знаходитесь ви в одній із цих систем, ймовірно, буде потрібно читання коду чи велика удача, оскільки взаємодія є маловірогідною в кожній спробі.

Інші корисні моменти:

  • Сигнал, що генерується вручну та надсилається в окремий процес (можливо, з kill), буде доставлений лише до цього процесу, незалежно від того, це він є батьком чи дитиною.
  • Порядок, по якому обробники сигналів запускаються між процесами, не визначений, тому ви не можете розраховувати на виконання будь-якого першого.
  • Якщо ви не визначите обробник переривання (або явно проігнорує сигнал), обидва процеси просто вийдуть з SIGINTкодом (поведінка за замовчуванням).
  • Якщо один обробляє сигнал несмертельно, а другий не робить, той без обробника загине, а другий продовжить.

Я припускаю, що снаряди можуть також втручатися в цікаві способи? Якщо це сигнал, що вони можуть потрапити в пастку, він може надіслати його своїм дітям? (І тоді є SIGHUP) (Все це може означати, що поки ОС не надсилає сигнали, дочірній процес може не впливати на сигнал батька ...)
Герт ван ден Берг,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.