以下是代码片段:
#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 ? ]
请忽略“收到的标志”和“内部...”行,因为它们是用于在代码中标记位置。
答案 0 :(得分:1)
父进程中未设置变量child1
。因此,父级中的kill()
调用将发出当前进程组中所有进程的信号。
此外,在信号处理程序中使用printf()
很少是安全的。这里看起来几乎是安全的,因为中断的函数是wait()
,它是异步信号安全的,但通常它是不安全的。
waitpid()
或wait4()
优先于wait()
,因为它们会让您等待特定的子流程。
答案 1 :(得分:0)
不会以任何方式共享三个进程的地址空间。因此变量'child1'和'child2'在进程之间是不同的。因此,当第一个孩子设置'child1'时,它不会影响父母中的'child1'变量。因此,当父节点向'child1'发送信号时,它将被发送到0 - 整个进程组。