gpt4 book ai didi

c - 进程同步与信号死锁情况

转载 作者:行者123 更新时间:2023-11-30 16:33:39 26 4
gpt4 key购买 nike

我需要同步父进程和子进程以在无限循环中按顺序工作,但一段时间后我陷入僵局。

不允许使用sleep、wait,必须用信号来实现同步。经过搜索,我发现了一个类似的问题,使用了暂停方法,在答案中建议使用 sigsuspend 而不是暂停。所以我不确定我的实现是否有问题或者我需要使用另一种方法来避免死锁

这是我的代码

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>

void catcher( int sig ) {
printf( "inside catcher() function\n" );
}

void timestamp( char *str ) {

time_t t;

time( &t );
printf( "%s the time is %s\n", str, ctime(&t) );
}


int main( int argc, char *argv[] ) {

struct sigaction sigact;
sigset_t block_set1,block_set2;

sigfillset( &block_set1 );
sigfillset( &block_set2 );
sigdelset( &block_set1, SIGUSR1 );
sigdelset( &block_set2, SIGUSR2 );

sigemptyset( &sigact.sa_mask );
sigact.sa_flags = 0;
sigact.sa_handler = catcher;
sigaction( SIGUSR1, &sigact, NULL );
sigaction( SIGUSR2, &sigact, NULL );

pid_t child_id;
child_id = fork ();
if (child_id == 0){

while(1){
printf("child send signal\n");
kill (getppid (), SIGUSR1);

printf("child wait signal\n");
sigsuspend( &block_set2 );
printf("child is going to die\n");
}


}else{
while(1){
timestamp( "before sigsuspend()" );
sigsuspend( &block_set1 );
timestamp( "after sigsuspend()" );

kill (child_id, SIGUSR2);

printf("parent is going to die\n");
}
}




return( 0 );
}

最佳答案

这个程序有一个问题,考虑这样一种情况:子进程/父进程甚至在使用 sigsuspend() 暂停执行之前就向父进程/子进程发送信号。在这种情况下,处理程序将被执行,之后就没有人会被执行他们中断 sigsupend() ,这可能会导致无限挂起状态。

引用手册页

int sigsuspend(const sigset_t *mask);

sigsuspend() temporarily replaces the signal mask of the calling process with the mask given by mask and then suspends the process until delivery of a signal whose action is to invoke a signal handler or to terminate a process.

我建议使用 sigwaitinfo() 代替,

int sigwaitinfo(const sigset_t *set, siginfo_t *info);

sigwaitinfo() suspends execution of the calling thread until one of the signals in set is pending (If one of the signals in set is already pending for the calling thread, sigwaitinfo() will return immediately.)

请找到相同的示例程序。

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>

void timestamp( char *str ) {

time_t t;

time( &t );
printf( "%s the time is %s\n", str, ctime(&t) );
}


int main( int argc, char *argv[] ) {

sigset_t parent_set, child_set;
sigset_t set;
siginfo_t info;

/*Mask SIGUSR2 and SIGUSR1 signal, you can choose this mask
* according to your requirement*/
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGUSR2);
sigprocmask(SIG_SETMASK, &set, NULL);

sigemptyset(&child_set);
sigaddset(&child_set, SIGUSR2);

sigemptyset(&parent_set);
sigaddset(&parent_set, SIGUSR1);

pid_t child_id;
child_id = fork ();
if (child_id == 0){

while(1){
printf("child send signal\n");
kill (getppid (), SIGUSR1);

printf("child wait signal\n");
/* Child will suspend its execution if parent did not notify it
* using signal(SIGUSR2), if parent has already notified sigwaitinfo()
* will return immediately
**/
sigwaitinfo(&child_set, &info );
printf("child is going to die\n");
}


}else{
while(1){
timestamp( "before sigwaitinfo()" );
/* Parent will suspend its execution if child did not notify it
* using signal(SIGUSR1), if child has already notified sigwaitinfo()
* will return immediately
**/
sigwaitinfo(&parent_set, &info );
timestamp( "after sigwaitinfo()" );

kill (child_id, SIGUSR2);

printf("parent is going to die\n");
}
}
}

希望这对您有帮助。

关于c - 进程同步与信号死锁情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49668479/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com