fork () và cách tín hiệu được phân phối đến các quy trình


13

Tôi lập trình rằng tôi đã viết trong C fork () tắt một tiến trình con. Không quá trình sẽ chấm dứt. Nếu tôi khởi chạy chương trình từ dòng lệnh và nhấn control-c, quá trình nào sẽ nhận được tín hiệu ngắt?

Câu trả lời:


20

Tại sao chúng ta không thử và xem? Đây là một chương trình tầm thường sử dụng signal(3)để bẫy SIGINTtrong cả quá trình cha mẹ và con cái và in ra một thông báo xác định quá trình khi nó đến.

#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;
}

Hãy gọi nó là test.c. Bây giờ chúng ta có thể chạy nó:

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

Các tín hiệu ngắt được tạo trong thiết bị đầu cuối được gửi đến nhóm quy trình hoạt động, ở đây bao gồm cả cha mẹ và con cái . Bạn có thể thấy rằng cả hai child_trapparent_trapđược thực thi khi tôi nhấn Ctrl- C.

Có một cuộc thảo luận dài về sự tương tác giữa forkvà tín hiệu trong POSIX . Phần vật chất nhất của nó ở đây là:

Một tín hiệu được gửi đến nhóm quy trình sau ngã ba () sẽ được gửi đến cả cha mẹ và con.

Họ cũng lưu ý rằng một số hệ thống có thể không hoạt động chính xác theo cách chính xác, đặc biệt khi tín hiệu đến rất gần với thời điểm fork(). Tìm hiểu xem bạn đang ở một trong những hệ thống đó có lẽ sẽ yêu cầu đọc mã hoặc rất nhiều may mắn, bởi vì các tương tác rất khó xảy ra trong mỗi lần thử.

Các điểm hữu ích khác là:

  • Một tín hiệu bằng tay tạo ra và gửi đến một quá trình cá nhân (có lẽ với kill) sẽ được cung cấp chỉ với quá trình đó, bất kể cho dù đó là cha mẹ hoặc con.
  • Thứ tự mà các trình xử lý tín hiệu chạy giữa các tiến trình không được xác định, do đó bạn không thể dựa vào việc thực thi trước.
  • Nếu bạn không xác định trình xử lý ngắt (hoặc bỏ qua tín hiệu rõ ràng), cả hai quá trình sẽ chỉ thoát với một SIGINTmã (hành vi mặc định).
  • Nếu một tín hiệu xử lý tín hiệu không gây tử vong và tín hiệu kia thì không, tín hiệu không xử lý sẽ chết và tín hiệu còn lại sẽ tiếp tục.

Tôi cho rằng vỏ cũng có thể can thiệp theo những cách thú vị? Nếu đó là một tín hiệu mà họ có thể bẫy, nó có thể gửi nó cho con của nó không? (Và sau đó là SIGHUP) (Tất cả điều này có thể có nghĩa là trong khi HĐH không gửi tín hiệu, một tiến trình con có thể không bị ảnh hưởng bởi tín hiệu cho phụ huynh ...)
Gert van den Berg
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.