fork 子进程问题

时间:2022-06-24 16:51:19

#include "apue.h"
#include <time.h>

int flog =1 ;

void alam_fn(int signo)
{
  printf("the clock time out");
  flog=0;
}


int get_time(void)
{
  time_t cur_time,cfg_time,ptr,tmp_time,now_time;
  struct tm *tmptr;
  int hour , min;
  pid_t pid;

  system("date");
  printf("input clock time:hour,min ");
  scanf("%d,%d",&hour,&min);

  printf("%d,%d",hour,min);
  tmp_time = time(&ptr);
  tmptr = localtime(&ptr);
  if( (cur_time = mktime(tmptr))<0)
      err_quit("time error!");
      printf("the current time is :%d:%d",tmptr->tm_hour,tmptr->tm_min);

   now_time = tmptr->tm_hour*60+tmptr->tm_min ;
   cfg_time = ((hour*60+min)-now_time)*60  ;

   printf("cfg_time:%d",cfg_time);
 
   if(cfg_time < 0)
        return 1;

return (cfg_time);

}

int
main(int argc,char *argv[])
{
  pid_t pid;
  int clock_time;
 
  if((clock_time = get_time())<0)
      err_exit(1,"gettime error");
  if(signal(SIGALRM,alam_fn)==SIG_ERR)
      err_sys("signal error:");
 
   if((pid=fork())<0)
       err_sys("fork error");
   else if(pid == 0)
   {  
   alarm(clock_time);
   while(flog);
   exit(0);
   }

   else       
   printf("parent exit first\n");
  
   return 0;



}


代码是我写的一个小练习,模拟闹钟的小程序,我的想法是 让父进程进行gettime操作 然后结束,然后子进程变成守护进程等待alarm超时,超时的时候 标准输出 “time out”  。现在的情况是功能可以实现 ,不过在超时的时候 子进程还把get_time函数里的那些打印信息打印了一遍,怎么可以不让打印这些信息呢?我试过用一个变量 当标志位可是也没有用。

5 个解决方案

#1


哦,父进程的缓冲区没有清空,同样被子进程继承了。
在fork()之前增加fflush()

#2


你说的具体指的那些打印信息?

#3


帮1楼解释几句:
输出到显示器是一个比较慢的动作。为了提高效率,printf的东西不是直接输出到显示器,而是先保存到一个缓冲区,与此同时程序会继续执行。然后经过一个或长或短的时间,才从缓冲区打印到显示器上。而缓冲区的内容是要在fork的时候被子进程复制过去的。
在这个例子里,父进程执行了get_time的时候,那里面printf的东西先到了缓冲区里. 如果在fork之前他们还没有输出到屏幕,就会被子进程复制过去, 结果就会在父进程和子进程各输出一次. 
解决的办法就是在fork之前强制把父进程缓冲区里的内容全都输出到屏幕。

1楼提到的fflush(stdout)是个好办法,也很保险。
还有个办法也可以试一下:把get_time里面的最后一个printf改成"cfg_time:%d \n". 通常如果输出了\n缓冲区的内容就很可能被送到屏幕了,不过这个不是很保险。

#4


在printf后使用fflush清空缓冲区

#5


这个printf函数的问题碰到的太多了,就是因为它把内容先放入缓冲区而后才输出,用的时候也特别小心,最好后边再加一个fflush(stdout);至少字符串也要带'\0',如果不知道很多时候让你郁闷至死都还不知道为什么死的.

#1


哦,父进程的缓冲区没有清空,同样被子进程继承了。
在fork()之前增加fflush()

#2


你说的具体指的那些打印信息?

#3


帮1楼解释几句:
输出到显示器是一个比较慢的动作。为了提高效率,printf的东西不是直接输出到显示器,而是先保存到一个缓冲区,与此同时程序会继续执行。然后经过一个或长或短的时间,才从缓冲区打印到显示器上。而缓冲区的内容是要在fork的时候被子进程复制过去的。
在这个例子里,父进程执行了get_time的时候,那里面printf的东西先到了缓冲区里. 如果在fork之前他们还没有输出到屏幕,就会被子进程复制过去, 结果就会在父进程和子进程各输出一次. 
解决的办法就是在fork之前强制把父进程缓冲区里的内容全都输出到屏幕。

1楼提到的fflush(stdout)是个好办法,也很保险。
还有个办法也可以试一下:把get_time里面的最后一个printf改成"cfg_time:%d \n". 通常如果输出了\n缓冲区的内容就很可能被送到屏幕了,不过这个不是很保险。

#4


在printf后使用fflush清空缓冲区

#5


这个printf函数的问题碰到的太多了,就是因为它把内容先放入缓冲区而后才输出,用的时候也特别小心,最好后边再加一个fflush(stdout);至少字符串也要带'\0',如果不知道很多时候让你郁闷至死都还不知道为什么死的.