在 Linux 中的不同线程之间缓冲 `printf` 输出

Yua*_*Wen 0 c linux multithreading buffering

这是我的代码:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>

pthread_t ntid;void
printids(const char *s) {
  printf("%s \n", s);
}

void *
thr_fn(void *arg)   {
  printids("new thread: ");
  return((void *)0);
}

int
main(void)  {
  pthread_create(&ntid, NULL, thr_fn, NULL);
  printids("main thread:");
}
Run Code Online (Sandbox Code Playgroud)

我在 Red Hat Enterprise Linux Workstation 版本 6.5 上运行它。
这是我的编译命令

gcc -ansi -g -std=c99 -Wall -DLINUX -D_GNU_SOURCE threadid.c -o threadid -pthread -lrt -lbsd

这是输出:

主线程:
新线程:
新线程:

为什么“新线程”已打印两次?我怀疑这可能与 Linux 中的缓冲机制有关。但是在我添加fflush(stdout)fsync(1)在每个函数的末尾之后。输出几乎相同。

如果您多次运行该程序。输出不同:

主线程:
新线程:

或者

主线程:
新线程:
新线程:

或者

主线程:

Aja*_*iya 5

正如您提到的,大多数 libc 库都会缓冲输出。并且在程序结束时(当主线程退出时),它们会刷新所有缓冲区并退出。

您的新线程可能已经刷新了输出,但在它可以更新缓冲区的状态之前,主程序退出并且清理代码再次刷新了相同的缓冲区。由于这些缓冲区对于线程来说是本地的,我确信它们不会有并发机制。但由于这种罕见的情况,它可能会变得一团糟。

你可以试试

err = pthread_create(&ntid, NULL, thr_fn, NULL);
printids("main thread:");
pthread_join(ntid, NULL);
Run Code Online (Sandbox Code Playgroud)

在main函数的最后,检查问题是否解决。

这将导致您的主函数等待新线程完成(包括它所做的刷新操作)。