一个c程序, fork 一个子进程并从键盘获取int数字长达10秒,10秒后停止读取并检查是否读取了任何数字,如果没有读取任何数字,则终止子进程,否则将打印读取屏幕上的数字并终止,不显示结果。
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>
#include<string.h>
#include<sys/wait.h>
#include<sys/errno.h>
int status,j,i=0;
pid_t son1, son2;
int string[20];
char s[5];
void handler(int signum)
{
if(i==0)
kill(son1,SIGKILL);
}
void signal_handler_1(int sig_num)
{
printf("\nI sent the signal SIGUSR1 to my child\n");
}
main(){
son1=fork();
if(son1==0)
{
signal(SIGUSR1 , signal_handler_1);
printf("I'm son1, my id is: %d\n", getpid());
pause();
printf("I'm son1 exitting: %d\n", getpid());
exit(1);
}
if(son1>0){
printf("I'm father, my id is: %d\n", getpid());
signal(SIGALRM,handler);
alarm(10);//how can i terminate the reading process after alarm??
while(fgets(s,5,stdin)!=NULL)
{
sscanf(s,"%d",&string[i]);
i++;
}
for(j=0;j<i;j++)
printf("%d\n",string[j]);
kill(son1,SIGUSR1);
wait(&status);
}
return 0;
}
最佳答案
运行 SIGALRM 的信号处理程序后,父级返回到 while 循环。
另外,就像linkdd所说,请更详细地描述问题。
在您的代码中,父级向子级发送 SIGKILL,并且子级变得失效,即“僵尸”,因为父级被卡住了。家长永远不会注意到 10 秒已经过去,并永远读取输入。
这不是最漂亮的方式,但这会让它起作用。
定义全局
int alarm_received = 0;
编辑父信号处理程序以在警报响起时设置标志。
void handler(int signum)
{
if(i==0){
kill(son1,SIGUSR1);
}
alarm_received = 1;
}
子信号处理程序可能是这样的。在信号处理程序中调用 printf 是不好的。
void signal_handler_1(int sig_num)
{
char msg[] = "Child received SIGUSR1\n";
write(STDOUT_FILENO, msg, sizeof(msg));
}
更改 while 循环以检查信号是否已发送。所以 parent 不会陷入困境。
while(alarm_received == 0)
{
fgets(s,5,stdin);
sscanf(s,"%d",&string[i]);
i++;
}
它仍然相当困惑。 fgets() 在收到信号后很可能需要(取决于操作系统)一个空行,因为 read() (在 fgets 内部)由操作系统重新启动。输入的解析也非常脆弱。
关于c - fork 一个 child ,从控制台读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14590683/