fprintf以错误的顺序打印数据

时间:2011-04-28 00:42:33

标签: c printf

我用C语言编写程序,将一些数据输出到标准输出。我使用了printf但我需要将数据保存到文件中,因此我将其更改为fprintf。问题是,使用fprintf,数据的顺序错误,无关紧要,如果输出是stdout或文件。

  if(...) {
    out = fopen(param.F, "w");
  } else {
    out = stdout;
  }

  // some code here
  fprintf(out, "a");
  // more code
  fprintf(out, "b");
  ....

如果这样,输出总是不同的。有时它是

  

ACB

有时它是

  

驾驶室

等...我尝试了setbuf和fflush的各种组合,但没有一个帮助过。

编辑:重要的是要知道,我在程序中使用了一些fork(),但正如我之前提到的,使用printf时没有问题。

这是我的输出:

1:理发师:检查

2:客户1:已创建

3:客户1:进入

5:理发师:准备好了

6:客户1:准备好了

4:客户2:已创建

7:理发师:完成了

8:理发师:检查

9:客户2:进入

10:客户1:服务

11:理发师:准备好了

12:客户2:准备好了

13:理发师:完成了

14:理发师:检查

15:客户2:服务

应该按号码排序。该计划的结构如下:

int main() {
  pid = fork();
  if(pid == 0) {
    // barber printfs
  } else if (pid > 0) {
    // customer printfs
  } 
}

2 个答案:

答案 0 :(得分:2)

(无法发表评论,必须回答......)

不,不是printf / fprintf缓冲区不同,如果你做fprintf(stdout,...)或printf(....),FILE *对象是相同的。

有几个进程正在写入同一个文件,并且由于没有同步和每个进程中的不同缓冲,输出都搞砸了。

答案 1 :(得分:1)

printf和fprintf将有不同的设备驱动程序缓冲。

正如你所说你正在使用fork,并根据输出,我推断代码类似于

  1. 打开文件
  2. 写入数据
  3. 在这种情况下,由于写入按随机顺序发生,因此会产生不同的顺序,具体取决于每个子进程的调度时间。

    最简单的解决方案是将应用程序包装在shell脚本中,然后通过tee运行二进制文件 - 这样您登录到stdout的所有内容也会转到文件中。

    如果您需要更复杂的解决方案,则需要在进程之间设置IPC机制,并在父进程中执行所有写操作。

    一种方法是在fork之前将stdout设置为管道(来自socketpair),并从父进程中的管道读取(使用select()以避免阻塞),然后登录到屏幕/文件。在使用freopen之前你需要dup()stdout以避免丢失它。我可能错过了一些事情,因为我有一段时间没有这样做。