簡體   English   中英

C子進程未收到SIGINT信號

[英]C child process doesn't receive SIGINT signal

我在處理信號時遇到問題。 我正在創建一個簡單的Web服務器,但我不明白為什么我的初始進程成功捕獲並處理了SIGINT信號,但是子進程對其fork()似乎不這樣做。 這是我的代碼:

#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include "thpool.h"
#include <pthread.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/sendfile.h>

int asc;
threadpool thpool;

void sighand(int sig) { //function handler
    if (sig == SIGINT) {
        printf("ctr-c recived\n");
        go = 0;
        thpool_destroy(thpool);
        shutdown(asc, 2);
        close(asc);
        int a = 1;
        setsockopt(asc, SOL_SOCKET, SO_REUSEADDR, &a, sizeof(int));
        exit(2);
}

void fun(void *client_socket) { 
    int sock = *(int*)client_socket;
    char buffer[1024]; 
    int n = read(sock, buffer, BUFFERSIZE);
    printf("%s\n", buffer);
}

int main() {
    int pid;

    if (signal(SIGINT, sighand) == SIG_ERR) //signal function
        perror("signal failed\n);
    pid = fork();
    if (pid == 0) { //new process
        int port = 8666, client_socket;
        struct sockaddr_in server, client;
        pthread_mutex_t M;
        pthread_mutex_init(&M,NULL);
        int parent = getppid();
        value = kill(parent, SIGTERM);  //kill the parent
        if (value == 0)
            printf("dead parent\n");
        else
            perror("errore");
        thpool = thpool_init(2); 

        //creazione socket
        asc = socket(AF_INET, SOCK_STREAM, 0); //new socket
        printf("\nsocket aperto\n");
        bzero((char *)&server, sizeof(server));

        //inizializzazione
        memset(&server, 0, sizeof(server));
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = INADDR_ANY;
        server.sin_port = htons(port);
        bind(asc, (struct sockaddr *)&server, sizeof(struct sockaddr_in)
        printf("bind effettuata\n");
        listen(asc, 40) 
        printf("listen effettuata\n");
        printf("in attesa di connessione....\n");
        client_leng = sizeof(client);
        while (go) {
            if ((client_socket = accept(asc, (struct sockaddr *)&client, &client_leng)) < 0) {
                perror("accept fallita");
                exit(0);
            } else {
                pthread_mutex_lock(&M);
                printf("accept effettuata\n");
                thpool_add_work(thpool, (void *)fun, (void *)&client_socket);
                puts("handler assigned\n");
                pthread_mutex_unlock(&M);
            }
        }
    }

TL; DR :您所發出的信號與您認為的信號不同。

您在注釋中提到,您試圖通過在鍵盤上鍵入CTRL-C向過程提供SIGINT 當您想殺死終端的前台進程組然后擁有鍵盤時,這很好。 假設您從外殼程序窗口啟動程序,並且沒有做任何事情使其自身進入后台,則初始進程確實將在前台進程組中,並且如果您從不使用fork()那么您所做的任何更改都不會更改,直到進程終止。 因此,在該終端中鍵入CTRL-C將為該進程傳遞一個SIGINT

但是,當初始進程終止時,啟動它的外殼會將其放回前台。 您可以通過鍵入命令來檢查它。 此外,在初始進程成功fork()一個child的情況下,當shell將自己置於前台時,child及其進程組將移入后台。 那時,您鍵入的任何CTRL-C都將轉到外殼程序 (忽略它),而不是Web服務器進程的子進程。

您可以通過kill命令將SIGINT發送到在后台運行或沒有控制終端的進程,例如

kill -INT 12345

如果在fork情況下使用該方法將SIGINT傳遞給子進程,則將看到該進程的已注冊信號處理程序將按其應有的方式捕獲並處理該信號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM