0

分叉一个孩子并从键盘获取 int 数字长达 10 秒的 ac 程序,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;
}
4

1 回答 1

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 循环以检查信号是否已发送。所以父母不会卡住。

while(alarm_received == 0)
{
    fgets(s,5,stdin);
    sscanf(s,"%d",&string[i]);
    i++;
}

它仍然很乱。fgets() 在收到信号后很可能需要(取决于操作系统)一个空行,因为 read() (在 fgets 内)由操作系统重新启动。输入的解析也很脆弱。

于 2013-01-29T19:35:43.240 回答