c - 信号处理程序行为

标签 c linux signals handler kill

我只是有一些关于系统调用 signal、kill 和信号处理程序的问题。 我有这段代码:

int figlio=-1;
int main(int argc,char* argv[])
    int pid1,pid2,dormi,numero;
    float reciproco;
    signal(SIGUSR1,gestore);
    signal(SIGUSR2,gestore);
    numero=atoi(argv[1]);
    printf("Numero %d\n\n",numero);
    fflush(stdout);
    pid1=fork();
    if(pid1>0)  //PADRE
    {
        pid2=fork();
        if(numero%2 == 0)
            kill(pid1,SIGUSR1);
        else
            kill(pid2,SIGUSR2);
        wait(NULL);
        wait(NULL);
    }
    if(pid1 == 0)   //FIGLIO1
    {   
        //sleep(1);
        printf("%d\n",figlio);
        if(figlio == 1)
        {
            numero=numero*numero*numero;
            fflush(stdout);
            printf("Ho eseguito il cubo %d\n",numero);
        }
        else
        {
            pause();
            if(figlio == 1) //Se il gestore di SIGUSR1 è partito
            {
                fflush(stdout);
                printf("Ciao dal figlio 1\n");
            }
        }
        printf("Figlio1 termina\n\n");
        exit(0);
    }
    if(pid2 == 0)   //FIGLIO2
    {
        if(figlio == 2)
        {
            dormi=numero;
            reciproco=(float)numero;
            reciproco=1/reciproco;
            fflush(stdout);
            printf("Ho eseguito il reciproco %f\n",reciproco);
            sleep(dormi);
            fflush(stdout);
            printf("Mando un segnale a mio fratello %d\n",pid1);
            kill(pid1,SIGUSR1);
        }
        else
            printf("Arrivederci e grazie\n");
        printf("Figlio2 termina\n\n");
        exit(0);
    }   
    return 0;
}

void gestore(int signo)
{
    if(signo == SIGUSR1)
        figlio=1;
    else
        figlio=2;
}

1) 不明白为什么第一个child中的第一个printf, return -1 without a sleep(1) before...好像handler是在child开始之后执行的。
2)当一个 child 被杀死时,调度器在 child 身上工作还是继续在父亲身上?
3) handler是在发送kill时执行还是调度器在child上工作时执行?

最佳答案

  1. fork() 之后,父进程和子进程处于竞争状态。无法保证父级有机会在子级到达 printf() 调用之前向子级发出对 kill() 的调用。

  2. 如果有多个处理器,两个进程可以同时运行。否则,如果子进程当前未运行,Linux 将设置一些内部状态,以便在子进程下次运行时将信号传递给子进程,如果进程尚未运行,它会将进程标记为可运行。

  3. 如果子进程当前正在运行,信号会立即得到处理。否则,它会在 child 下次运行时处理。处理程序作为处理信号的结果运行。

关于c - 信号处理程序行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50030769/

相关文章:

并发访问和释放堆对象

c - 在 C 中,如果数组在声明时初始化,则维度是可选的。为什么?

linux - 连接 ioctl 和驱动程序操作

c++ - Unix Socket返回ECONNRESET,服务器甚至没有得到accept来停止阻塞

linux - 参数类型 : "const char __user *const __user *argv" 的含义是什么

haskell - 中断 MonadState 中冗长的纯计算

c - 指向 const 结构的指针,成员还能被修改吗?

c - TCP 标志过滤器的十六进制、按位或反转

c - 不要在 epoll_wait 中终止程序

c - 对音频信号应用滤波器时的不同输出