【问题标题】:fork() and system() calls not working as I expectfork() 和 system() 调用没有像我预期的那样工作
【发布时间】:2014-05-10 23:51:54
【问题描述】:

我正在使用 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;
     }

【问题讨论】:

  • 难道不是因为printf 正在缓冲您的消息而不是立即输出吗?尝试在消息末尾添加\n 以刷新其缓冲区。
  • @HalimQarroum 完全正确。打印到stderr 或在printf 之后致电fflush(stdout),您应该会看到您的期望。我相信换行符"\n" 是否会导致刷新取决于系统。

标签: c fork system


【解决方案1】:

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

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

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

【讨论】:

  • 就是这样......我没有想到我应该刷新缓冲区。以为叉子退出时它会被冲洗掉。
【解决方案2】:

这个问题有两个部分。

  1. 您使用printf() 并且不要用换行符终止消息。
  2. 您使用 _exit() 故意避免刷新打开文件流(例如标准输出)上的缓冲输出。

基本修复很简单——正如Halim Qarroum 在他的answer 中准确诊断的那样:

  1. 在输出消息中包含换行符。
  2. 如果不能包含换行符,请包含 fflush(stdout)flush(0)
  3. 或使用exit() 代替_exit()

每一个都将修复丢失的消息。作为一般规则,如果您希望显示消息,请以换行符结束。如果不这样做,请确保它是使用 fflush() 生成的,或者确保使用 exit() 刷新缓冲区。

【讨论】:

    猜你喜欢
    • 2016-06-19
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    • 2023-01-01
    • 2023-03-14
    相关资源
    最近更新 更多