1 Tại sao SIGINT ngừng ngủ nhiều hơn một lần?

câu hỏi được tạo ra tại Wed, May 8, 2019 12:00 AM

Tôi không hiểu tại sao sau lần thực hiện chức năng kill đầu tiên, chức năng ngủ không tạm dừng quá trình cha. Sau khi SIGINT được phân phối, nhiều quy trình được tạo. Hơn nữa, có vẻ như một số lượng quá trình khác nhau được tạo ra. Là một trình xử lý cho SIGINT cần thiết để làm sạch SIGINT đầu tiên khỏi các tín hiệu đang chờ xử lý?

void handler(int s) {
    int status;
    wait(&status);
    printf("\n in the handler");
    if (WIFSIGNALED(status)) {
        int sig=WTERMSIG(status);
        printf("\n child stopped by signal %d\n",sig);
    }
    if (WIFEXITED(status)) {
        int ex=WEXITSTATUS(status);
        printf("\n child stopped with exist status %d\n",ex);
    }
}

int main() {
    int pid,len, count, ret;
    char s[1024];
    signal(SIGCHLD,handler);
    while(1) {
        pid=fork();
        if (pid==0) {
            printf("\n Write something ");
            scanf("%s",s);
            len=strlen(s);
            printf("\n Characters: %d",len);
            return 1;
        }
        else {
            sleep(20);
            kill(pid,SIGINT);
        }
    }
}
    
1
  1. Hãy thử chạy với strace để xem điều gì đang xảy ra.
    2019-05-08 16: 30: 40Z
  2. Hai vấn đề tiềm ẩn. Trước tiên, bạn không thể gọi printf() một cách an toàn trong bộ xử lý tín hiệu vì nó không an toàn như tín hiệu. Xem stackoverflow.com/questions 432467694 /Cách cho một câu hỏi ví dụ. Thứ hai, bạn có thể muốn sử dụng sigaction() thay vì signal() .
    2019-05-08 16: 58: 54Z
1 Câu trả lời                              1                         

SIGCHLD từ vụ gây tử vong trẻ em trước đó kill sẽ đến ngay khi bạn ở sleep tiếp theo.

Ngủ là một chức năng gián đoạn. Nếu một trình xử lý tín hiệu chạy trong khi luồng của bạn nằm trong đó, sleep sẽ hủy bỏ. Vì vậy, sau đó bạn tiến hành kill tiếp theo, điều này sẽ gián tiếp gây ra SIGCHLD khác rất có thể sẽ xảy ra khi giấc ngủ lặp lại tiếp theo của bạn, dẫn đến một số giấc ngủ bị bỏ qua.

Nếu bạn chèn sleep(1) trước fork(), thì (thực tế) nên thay đổi thời gian vừa phải để sleep(20); tiếp theo không bị gián đoạn.

(Tôi đang coi đây là một thử nghiệm nhanh và bẩn. Không có cách nào để dựa vào "các điều chỉnh" như thế này trong mã sản xuất (hoặc sử dụng printf trong xử lý tín hiệu cho vấn đề đó). )

    
2
2019-05-08 23: 15: 40Z
  1. Làm { int t = 20; while (0 <= (t = sleep(t))); } thay vì chỉ sleep(20); cũng có thể giúp ích.
    2019-05-09 04: 56: 19Z
  2. t ở trên phải là unsigned int.
    2019-05-09 05: 30: 05Z
nguồn đặt đây