【发布时间】:2020-12-31 12:35:00
【问题描述】:
我正在研究写入文件与管道的速度。请看这段代码,除非有命令行参数,否则写入文件句柄,否则写入管道:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <chrono>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
void do_write(int fd)
{
const char* data = "Hello world!";
int to_write = strlen(data), total_written = 0;
int x = 0;
auto start = chrono::high_resolution_clock::now();
while (x < 50000)
{
int written = 0;
while (written != to_write)
{
written += write(fd, data + written, to_write - written);
}
total_written += written;
++x;
}
auto end = chrono::high_resolution_clock::now();
auto diff = end - start;
cout << "Total bytes written: " << total_written << " in " << chrono::duration<double, milli>(diff).count()
<< " milliseconds, " << endl;
}
int main(int argc, char *argv[])
{
//
// Write to file if we have not specified any extra argument
//
if (argc == 1)
{
{
int fd = open("test.txt", O_WRONLY | O_TRUNC | O_CREAT, 0655);
if (fd == -1) return -1;
do_write(fd);
}
return 0;
}
//
// Otherwise, write to pipe
//
int the_pipe[2];
if (pipe(the_pipe) == -1) return -1;
pid_t child = fork();
switch (child)
{
case -1:
{
return -1;
}
case 0:
{
char buf[128];
int bytes_read = 0, total_read = 0;
close(the_pipe[1]);
while (true)
{
if ((bytes_read = read(the_pipe[0], buf, 128)) == 0)
break;
total_read += bytes_read;
}
cout << "Child: Total bytes read: " << total_read << endl;
break;
}
default:
{
close(the_pipe[0]);
do_write(the_pipe[1]);
break;
}
}
return 0;
}
这是我的输出:
$ time ./LinuxFlushTest pipe
Total bytes written: 600000 in 59.6544 milliseconds,
real 0m0.064s
user 0m0.020s
sys 0m0.040s
Child: Total bytes read: 600000
$ time ./LinuxFlushTest
Total bytes written: 600000 in 154.367 milliseconds,
real 0m0.159s
user 0m0.028s
sys 0m0.132s
从time 输出和我的 C++ 代码时序中,您可以看到写入管道比文件快得多。
现在,据我所知,当我们调用write() 时,数据将被复制到内核缓冲区,此时pdflush 样式线程实际上会将其从页面缓存刷新到底层文件。 我没有在我的代码中强制刷新,因此没有磁盘查找延迟。
但是我不知道(而且似乎无法找到:是的,我看过内核代码但迷失在其中,所以没有像“看代码”这样的 cmets请) 写入管道时会发生什么不同:它不只是内核中某个孩子可以读取的内存块吗?那么,为什么它比写入文件的基本相同的过程要快得多?
【问题讨论】: