gpt4 book ai didi

c - Unix 表示奇怪的行为。 ( child 多次退出)

转载 作者:太空宇宙 更新时间:2023-11-03 23:44:47 24 4
gpt4 key购买 nike

我正在练习使用 unix 信号进行编程,我是新手,所以我写了以下程序:http://wklej.org/id/2253905/ ,我正在按以下方式编译:gcc -Wall -o signals signals.c

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>

void child_work(int l);
void create_children(int n, int l);
void parent_work(int k, int p);
int sethandler( void (*f)(int), int sigNo);
void child_handler(int sig);
void parent_handler(int sig);
void sigchld_handler(int sig);
void usage(void);

volatile sig_atomic_t last_signal = 0;

int sethandler( void (*f)(int), int sigNo)
{
struct sigaction act;
memset(&act, 0, sizeof(struct sigaction));
act.sa_handler = f;
if (-1==sigaction(sigNo, &act, NULL))
return -1;

return 0;
}



void sigchld_handler(int sig) {
pid_t pid;
for(;;)
{
pid=waitpid(0, NULL, WNOHANG);
if(pid==0) return;
if(pid<=0)
{
if(errno==ECHILD)
{
printf("[%d] No more children parent quits.",getpid());
exit(EXIT_SUCCESS);
}

perror("waitpid:");
exit(EXIT_FAILURE);
}
}
}

void child_handler(int sig)
{
printf("[%d] received signal %d\n", getpid(), sig);
last_signal = sig;
if(last_signal==SIGUSR1)
if(0==kill(0,SIGUSR2))
printf("[%d] SENDING signal %d\n", getpid(), SIGUSR2);
else
perror("kill:");

}

void parent_handler(int sig) {
printf("[%d] received signal %d\n", getpid(), sig);
last_signal = sig;
}

void child_work(int t)
{
int s;
srand(getpid());
s=rand()%(t-1)+2;
struct timespec tt, tn = {s,0};
for(tt=tn;nanosleep(&tt,&tt);)
if(EINTR!=errno)
perror("nanosleep:");



printf("[%d] dies",getpid());
exit(EXIT_SUCCESS);
}


void create_children(int n, int t)
{
while (n-->0)
{
switch (fork())
{
case 0:
if(sethandler(child_handler,SIGUSR1))
{
perror("Seting child SIGUSR1:");
exit(EXIT_FAILURE);
}

if(sethandler(child_handler,SIGUSR2))
{
perror("Seting child SIGUSR2:");
exit(EXIT_FAILURE);
}

child_work(t);
exit(EXIT_SUCCESS);

case -1:
perror("Fork:");
exit(EXIT_FAILURE);


}
}
}

void usage(void){
fprintf(stderr,"USAGE: signals n t\n");
fprintf(stderr,"n - number of children > 0\n");
fprintf(stderr,"t - max lifetime of child process\n");
}

int main(int argc, char** argv)
{
int n,t;
//int childcount;
if(argc!=3)
{
usage();
return EXIT_FAILURE;
}

n = atoi(argv[1]);
t = atoi(argv[2]);

if (n<=0 || t<=1) {
usage();
return EXIT_FAILURE;
}

if(sethandler(SIG_IGN,SIGUSR1))
{
perror("Seting parent SIGUSR1:");
exit(EXIT_FAILURE);
}

if(sethandler(parent_handler,SIGUSR2))
{
perror("Seting parent SIGUSR2:");
exit(EXIT_FAILURE);
}

if(sethandler(sigchld_handler,SIGCHLD))
{
perror("Seting parent SIGCHLD:");
exit(EXIT_FAILURE);
}

create_children(n, t);
struct timespec tt, tn = {1,0};

while(1)
{
for(tt=tn;nanosleep(&tt,&tt);)
if(EINTR!=errno) perror("nanosleep:");
if(0==kill(0,SIGUSR1))
printf("[%d] SENDING signal %d\n", getpid(), SIGUSR1);
else
perror("kill:");

}




return EXIT_SUCCESS;
}

当我运行它时 ./program 3 3(它产生 3 个 child )我得到奇怪的输出,如:

[2835] dies[2836] dies[2834] dies[2836] dies[2836] received signal 10
[2836] received signal 12
[2836] SENDING signal 12
[2835] dies

如您所见,[2835] 和 [2836] 死了 2 次,我只是想知道为什么它会这样?预先感谢您的帮助。

最佳答案

在信号处理函数中使用 printf() 会导致未定义的行为。我无法使用我的 Debian 8.3 虚拟机重现您的错误。行为将取决于操作系统。

Check here Async-signal-safe functions

关于c - Unix 表示奇怪的行为。 ( child 多次退出),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36519062/

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