fork()和system()调用不能按我的预期工作

时间:2014-05-10 23:51:55

标签: c fork system

我正在使用fork()和system()命令,当我运行此示例代码时,我发现子进程在系统调用完成后不会打印“Song complete ...”行。 这是正常的还是我错过了什么?

我认为system()已经完成了它的工作,然后返回到子进程并继续以愉快的方式退出或执行其他任务。这个代码示例不会发生这种情况。

     #include <sys/types.h> /* pid_t */
     #include <sys/wait.h>  /* waitpid */
     #include <stdio.h>     /* printf, perror */
     #include <stdlib.h>    /* exit */
     #include <unistd.h>    /* _exit, fork */

     int main(void)
     {
       pid_t pid;
       int i;
       pid = fork();

       if (pid == -1) {
          /*
           * When fork() returns -1, an error happened.
           */
          perror("fork failed");
          exit(EXIT_FAILURE);
       }
       else if (pid == 0) {
          /*
           * When fork() returns 0, we are in the child process.
           */
          printf("Hello from the child process!\n");
            system("aplay ./SOS_sample.wav");
          printf("Song complete...");
          _exit(EXIT_SUCCESS);  /* exit() is unreliable here, so _exit must be used */
       }
       else {
          /*
           * When fork() returns a positive number, we are in the parent process
           * and the return value is the PID of the newly created child process.
           */
          int status;
            printf("Waiting on the song to end...\n");
            for (i = 0;i<10;i++){
                    printf("%d\n",i);
                    }
          (void)waitpid(pid, &status, 0);
            for (i=0;i<10;i++){
                    printf("%d\n",i);
                    }
       }
       return EXIT_SUCCESS;
     }

2 个答案:

答案 0 :(得分:4)

可能是因为printf缓冲了您的消息,并且不立即将其输出到标准输出上。在这种情况下,由于您的子进程被立即杀死,您对printf的调用将完全被忽视。

尝试在邮件末尾添加\n以强制printf刷新其内部缓冲区:

printf("Song complete...\n");

答案 1 :(得分:1)

问题分为两部分。

  1. 您使用printf()并且不使用换行符终止消息。
  2. 您使用_exit()故意避免在打开的文件流(例如标准输出)上刷新缓冲输出。
  3. 基本修复很简单 - 由Halim Qarroum中的answer准确诊断:

    1. 在输出消息中包含换行符。
    2. 如果您不能包含换行符,请添加fflush(stdout)flush(0)
    3. 或使用exit()代替_exit()
    4. 每一项都将治愈失踪的信息。作为一般规则,如果要显示消息,请使用换行符结束。如果不这样做,请确保使用fflush()生成,或确保使用exit()来刷新缓冲区。