我有一个简单的程序(工作示例):
#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
上刷新。我想知道为什么在这种情况下它不打印。我读到输出流在程序退出时刷新。printf
在malloc
的内存中缓冲输出(我在我的实现中确认了这一点)。
我的问题(更多细节欢迎):
- 为什么注解掉对
execvp
的调用会导致输出被打印到stdout
上,但它不是按原样打印的?我的想法是,即使在ls
蚕食进程之后,它不会仍然被认为是程序退出吗? printf
的内存缓冲区会被视为输出流吗?- 一个与此问题完全无关的细节是我想知道为什么
zsh
上的文件描述符10
和bash
上的255
没有被我的进程继承。
1条答案
按热度按时间jgwigjjp1#
execvp
用新进程替换旧进程,所有打开的文件描述符保持打开状态,但C stdio库缓冲的数据不保留。C启动代码会在STDOUT文件描述符上附加一个新的FILE指针。关键是文件描述符是OS对象,而**FILE
指针**是C库对象,只保留OS对象。