C语言 为什么我没有看到printf缓冲区刷新?

ars1skjm  于 2023-04-19  发布在  其他
关注(0)|答案(1)|浏览(129)

我有一个简单的程序(工作示例):

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

int main() {
  pid_t my_pid = getpid();
  char str[30];

  sprintf(str, "/proc/%d/fd", my_pid);
  printf("hello, I am gonna print out: %s", str);

  execvp( "ls", (char *[]) { "ls", str, NULL } );

  return 0;
}

在Linux虚拟机上用gcc编译。我的问题是为什么发送到printf的输出从不打印。
我知道printf缓冲它的输出并且只在\n上刷新。我想知道为什么在这种情况下它不打印。我读到输出流在程序退出时刷新。printfmalloc的内存中缓冲输出(我在我的实现中确认了这一点)。
我的问题(更多细节欢迎):

  • 为什么注解掉对execvp的调用会导致输出被打印到stdout上,但它不是按原样打印的?我的想法是,即使在ls蚕食进程之后,它不会仍然被认为是程序退出吗?
  • printf的内存缓冲区会被视为输出流吗?
  • 一个与此问题完全无关的细节是我想知道为什么zsh上的文件描述符10bash上的255没有被我的进程继承。
jgwigjjp

jgwigjjp1#

execvp用新进程替换旧进程,所有打开的文件描述符保持打开状态,但C stdio库缓冲的数据不保留。C启动代码会在STDOUT文件描述符上附加一个新的FILE指针。关键是文件描述符是OS对象,而**FILE指针**是C库对象,只保留OS对象。

相关问题