在bash中重定向stdout与在C语言中使用fprintf写入文件(速度)的比较

7
我想知道哪个选项基本上更快。
最让我感兴趣的是重定向机制。我怀疑文件在程序开始时./program > file被打开,并在程序结束时关闭。因此,每次程序输出内容时,它应该只需写入文件,听起来很简单。是这样吗?那么我猜两个选项在速度方面应该是可比较的。
或者这是一个更复杂的过程,因为操作系统必须执行更多的操作?

2
Shell在启动程序之前就打开文件进行写入。 - Etan Reisner
没错,我在那方面没有说得很准确。 - thim
我认为这些东西是完全不同的。如果你正在用C编写程序,你会使用fprintf。当你在使用纯shell和打印输出的工具时,你将重定向输出。此外,如果你没有任何BASH怎么办?那么你肯定会使用fprintf - ForceBru
1
我认为重定向stdout或直接写入文件之间的性能差异可以忽略不计且无法测量。从操作系统的角度来看,实际上没有任何区别。 - Some programmer dude
3个回答

5

这些选项之间几乎没有什么区别(除了将文件作为严格选项会降低程序的灵活性)。

为了比较两种方法,让我们看看神奇实体FILE*背后的内容:

因此,在两种情况下,我们都有一个FILE*对象,一个文件描述符fd——连接到操作系统内核和内核基础设施的网关,该基础设施提供对文件或用户终端的访问,这应该是(除非libc具有一些特殊的stdout初始化器或内核专门处理fd = 1的文件)。

fopen()相比,bash重定向如何工作?

当bash重定向文件时:

fork()                      // new process is created
fd = open("file", ...)      // open new file
close(1)                    // get rid of fd=1 pointing to /dev/pts device
dup2(fd, 1)                 // make fd=1 point to opened file
close(fd)                   // get rid of redundant fd
execve("a")                 // now "a" will have file as its stdout
// in a
stdout = fdopen(1, ...)

当您自己打开文件时:

fork()                           // new process is created
execve("a")                      // now "a" will have file as its stdout
stdout = fdopen(1, ...)         
my_file = fopen("file", ...)     
    fd = open("file", ...)
    my_file = fdopen(fd, ...)

所以正如您所看到的,主要的Bash区别在于对文件描述符进行微调。


这就是我一直在寻找的答案。我怀疑它只是文件描述符的替换,但我不知道它是在哪个级别上执行的。谢谢你的回答,我的知识饥渴得到了满足 ;) - thim

3

是的,你说得对。速度将是相同的。两种情况唯一的区别在于哪个程序打开和关闭文件。当你使用shell重定向时,是shell打开文件并将句柄作为stdout提供给程序。当程序打开文件时,程序打开文件。之后,在两种情况下,句柄都是文件句柄,因此速度上应该没有任何区别。

顺带一提,写入stdout的程序可以以更通用的方式使用。例如,你可以这样说:

./program | ssh remotehost bash -c "cat > file"

这将导致程序输出被写入到remotehost上的file中。当然,在这种情况下,没有像你在问题中做的那样进行比较。

2

stdout 是一个 FILE 句柄,fprintf 写入文件句柄,因此在这两种情况下速度非常相似。实际上,printf("Some string") 等同于 fprintf(stdout, "Some string")。不再多说 :)


我知道那个。我很好奇bash是否会用文件句柄替换stdout句柄,或者机制完全不同。 - thim
每个进程都需要至少3个句柄:stdin、stdout和stderr。它不关心这些句柄来自哪里,只要能使用它们即可。例如,bash/cmd/终端会发送它们的窗口写入句柄。 - Cristik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接