c - linux 中进程的信号处理错误

标签 c linux process signals unix

以下是代码片段:

#include<sys/types.h>
#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>

sig_atomic_t child1 ;

sig_atomic_t child2 ;

void child1_handler( int sig_num )
{

     int ret ;

 if(sig_num == SIGUSR2 )
 {
    printf("\n Recieved sigusr2 for child1\n");

    ret = kill( getppid() , SIGUSR2 ) ;
    if( ret != 0 )

        kill( getpid() , SIGTERM );
 }
 else if(sig_num == SIGUSR1 )
 { 
    /* child 1 does something */
    printf("\n Recieved sigusr1 for child1\n");
    printf("\n child 1 is doing \n");

    kill( child2 , SIGUSR2 );
 }
}

void child2_handler( int sig_num )
{
if( sig_num == SIGUSR2 )
{
    /* child2 does somethign */
    printf("\n Recieved sigusr2 for child2\n");
    printf("\n child2 is doing \n");

    kill( child1 , SIGUSR2 );

    kill( getpid() , SIGTERM );
}
 }

 void parent_handler( int sig_num )
 {
int ret ;
if( sig_num == SIGUSR2 )
{
    printf("\n Recieved sigusr2 for parent\n");

    ret = kill( child1 , SIGUSR1 ) ;
    if( ret != 0 )
    {
        /* parent does something */

        printf( "\n Parent does something \n" );
        exit(0);
    }
}
   }


   int main()
   {
struct sigaction sa_parent , sa_child1 , sa_child2 ;
pid_t temp_id1 , temp_id2 ;
int temp ;

memset(&sa_parent , 0 , sizeof(sa_parent) ) ;
memset(&sa_child1 , 0 , sizeof(sa_child1) ) ;
memset(&sa_child2 , 0 , sizeof(sa_child2) ) ;

/* parent */

printf( " \n Inside parent \n" );

sa_parent.sa_handler = &parent_handler ;
sigaction( SIGUSR2 , &sa_parent , NULL );

temp_id1 = fork() ;

if( temp_id1 == 0 )
{
    child1 = getpid() ;

    /* child1 */

    printf("\n inside child1 \n" );

    sa_child1.sa_handler = &child1_handler ;    
    sigaction( SIGUSR1 , &sa_child1 , NULL ) ;
    sigaction( SIGUSR2 , &sa_child1 , NULL ) ;

    temp_id2 = fork() ;

    if( temp_id2 == 0 )
    {
        child2 = getpid() ;

        /* child2 */

        printf( "\n inside child2 \n" );

        sa_child2.sa_handler = &child2_handler ;
        sigaction( SIGUSR2 , &sa_child2 , NULL );

        kill( child1 , SIGUSR2 );
    }

    wait(&temp);
}

wait(&temp);
return 0 ;
   }

我希望输出首先描述

child1 is doing
child2 is doing
parent does something 

然而,产生的输出如下所示。

Inside parent 
inside child1 
inside child2 
Recieved sigusr2 for child1
Recieved sigusr2 for parent
Recieved sigusr1 for child1
child 1 is doing 
Recieved sigusr2 for child1
User defined signal 1

[ what is going wrong ? ]

请忽略“收到的标志”和“内部...”行,因为它们是用来标记代码中的位置的。

最佳答案

父进程中未设置变量 child1。因此,父进程中的 kill() 调用将向当前进程组中的所有进程发出信号。

此外,在信号处理程序中使用 printf() 很少是安全的。这里看起来几乎是安全的,因为被中断的函数是 wait(),它是异步信号安全的,但通常它是不安全的。

waitpid()wait4() 优于 wait(),因为它们让您等待特定的子进程。

关于c - linux 中进程的信号处理错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4200112/

相关文章:

linux - Bash for循环从文本文件运行命令

xml - 在 Linux 上运行进程的 shell 脚本

c# - 你如何取消提升子进程的特权

c - 符号可见性未按预期工作

c - 段错误(核心转储)——如何修复我的代码?

c++ - 字符字符串数组的初始化程序中的问题

linux - Linux/Mac 上的 Silverlight

linux - 为什么在 bash 命令后附加控制字符?

node.js - 在 Node.js 中运行异步进程

c - LD_PRELOAD 从根本上降低了 linux 下 C 的进程创建性能?