unix中使用PIPE_BUF的popen和write/read系统调用解释
在linux中,limits.h中定义的常量“PIPE\u BUF”是如何工作的。当我在系统调用读取(int-fd,void*buf,size\u t count)中将其用作计数时,,系统是否调用读取,每次返回一个字节,并等待它到达文件末尾? 下面的代码接受两个命令“last”和“sort”,并进行两次popen调用。 比如~$foo最后一次排序 在下面的代码中,我不理解如果读取只返回一次所有可用字节,为什么需要while循环。 还有,对popen的写入如何理解所有的输入已经被接收,现在是popen执行程序的时候了unix中使用PIPE_BUF的popen和write/read系统调用解释,unix,linux-kernel,popen,system-calls,limits,Unix,Linux Kernel,Popen,System Calls,Limits,在linux中,limits.h中定义的常量“PIPE\u BUF”是如何工作的。当我在系统调用读取(int-fd,void*buf,size\u t count)中将其用作计数时,,系统是否调用读取,每次返回一个字节,并等待它到达文件末尾? 下面的代码接受两个命令“last”和“sort”,并进行两次popen调用。 比如~$foo最后一次排序 在下面的代码中,我不理解如果读取只返回一次所有可用字节,为什么需要while循环。 还有,对popen的写入如何理解所有的输入已经被接收,现在是pop
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
int main (int argc, char* argv[])
{
FILE *fin, *fout;
char buffer[PIPE_BUF];
int n;
if (argc < 3)
{
printf("Need two parameters.\n");
exit(1);
}
fin=popen(argv[1], "r");
fout=popen(argv[2],"w");
fflush(fout);
while ((n=read(fileno(fin), buffer, PIPE_BUF)) > 0)
{
write(fileno(fout), buffer, n);
}
pclose(fin);
pclose(fout);
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
文件*fin,*fout;
字符缓冲区[PIPE_BUF];
int n;
如果(argc<3)
{
printf(“需要两个参数。\n”);
出口(1);
}
fin=popen(argv[1],“r”);
fout=popen(argv[2],“w”);
福鲁斯(福特);
而((n=read(fileno(fin)、buffer、PIPE_BUF))>0)
{
写入(文件号(fout),缓冲区,n);
}
pclose(fin);
pclose(fout);
返回0;
}
根据linux源代码,没有迹象表明read()
系统调用一次读取1个字节。这将是非常愚蠢的,所以我从未想过托瓦尔兹会接受这一点
回答你的问题:
read()
函数用一些数据填充缓冲区,要读取超出缓冲区容量的数据,您需要一直调用它,直到您读取了所需的所有数据。这就是为什么要使用循环。如果有一个与您正在读取的文件一样大的缓冲区,则效率不高。popen
立即执行程序,并创建一个连接到该程序输入/输出的管道。
所有程序同时运行
read
调用等待某些数据(至少一个字节)可用,然后返回所有可用数据并放入缓冲区。
如果管道另一端的程序写入了多个字节,那么您也可以读取多个字节
您需要一个循环,因为其他程序稍后可能会写入更多数据。
只有当管道的写入端关闭时,read
才会返回零