从两个管道中读取数据,然后用C语言打印在标准输出上
我有两个管道,它们都在随机点获得不同的数据。我想要的是将内容从两个管道打印到标准输出 我的代码在process1中对此进行了说明:从两个管道中读取数据,然后用C语言打印在标准输出上,c,pipe,stdout,C,Pipe,Stdout,我有两个管道,它们都在随机点获得不同的数据。我想要的是将内容从两个管道打印到标准输出 我的代码在process1中对此进行了说明: while (1) { read(pipe1[0], &buff, sizeof(char)); write(1, &buff, sizeof(char)); read(pipe2[0], &buff2, sizeof(char)); write(1, &buff2, sizeof(char)); } 但是,这
while (1) {
read(pipe1[0], &buff, sizeof(char));
write(1, &buff, sizeof(char));
read(pipe2[0], &buff2, sizeof(char));
write(1, &buff2, sizeof(char));
}
但是,这不起作用,因为当数据来自另一条管道时,如果没有数据,则可以阻止一次读取
如何从两个管道同时打印而不被一个管道阻塞?或者关于如何解决此问题的任何其他建议都是受欢迎的。用于在两个套接字上等待。当数据准备就绪时,它将告诉您哪些管道有可用的数据
void setnonblocking(int fd) {
int opts;
opts = fcntl(fd,F_GETFL);
if (opts < 0) {
perror("Couldn't get file descriptor flags");
exit(EXIT_FAILURE);
}
opts = (opts | O_NONBLOCK);
if (fcntl(fd,F_SETFL,opts) < 0) {
perror("Couldn't set file descriptor to non-blocking");
exit(EXIT_FAILURE);
}
return;
}
#ifndef BUFSIZE
# define BUFSIZE 1024
#endif
void cat(fd_set* waiting, int fd) {
static char buf[BUFSIZE];
int readCnt;
if (FD_ISSET(fd, waiting)) {
while ((readCnt = read(fd, buf, BUFSIZE)) > 0) {
write(stdout, buf, readCnt);
}
if (readCnt < 0) {
perror("Error reading from pipe");
}
}
}
...
{
fd_set pipes, readable;
setnonblocking(pipes1[0]);
setnonblocking(pipes2[0]);
FD_ZERO(&pipes);
FD_SET(pipe1[0],&pipes);
FD_SET(pipe2[0],&pipes);
int ready;
while (1) {
if ((ready = select(2, &pipes, NULL, NULL, NULL)) > 0) {
cat(&pipes, pipe1[0]);
cat(&pipes, pipe2[0]);
} else {
// no time limit, so there was an error
perror("Error waiting for input");
exit(EXIT_FAILURE);
}
FD_SET(pipe1[0],&pipes);
FD_SET(pipe2[0],&pipes);
}
}
请注意,除非出现错误,否则上述操作将永远运行。您可能希望程序在某个点停止。用于在两个套接字上等待。当数据准备就绪时,它将告诉您哪些管道有可用的数据
void setnonblocking(int fd) {
int opts;
opts = fcntl(fd,F_GETFL);
if (opts < 0) {
perror("Couldn't get file descriptor flags");
exit(EXIT_FAILURE);
}
opts = (opts | O_NONBLOCK);
if (fcntl(fd,F_SETFL,opts) < 0) {
perror("Couldn't set file descriptor to non-blocking");
exit(EXIT_FAILURE);
}
return;
}
#ifndef BUFSIZE
# define BUFSIZE 1024
#endif
void cat(fd_set* waiting, int fd) {
static char buf[BUFSIZE];
int readCnt;
if (FD_ISSET(fd, waiting)) {
while ((readCnt = read(fd, buf, BUFSIZE)) > 0) {
write(stdout, buf, readCnt);
}
if (readCnt < 0) {
perror("Error reading from pipe");
}
}
}
...
{
fd_set pipes, readable;
setnonblocking(pipes1[0]);
setnonblocking(pipes2[0]);
FD_ZERO(&pipes);
FD_SET(pipe1[0],&pipes);
FD_SET(pipe2[0],&pipes);
int ready;
while (1) {
if ((ready = select(2, &pipes, NULL, NULL, NULL)) > 0) {
cat(&pipes, pipe1[0]);
cat(&pipes, pipe2[0]);
} else {
// no time limit, so there was an error
perror("Error waiting for input");
exit(EXIT_FAILURE);
}
FD_SET(pipe1[0],&pipes);
FD_SET(pipe2[0],&pipes);
}
}
请注意,除非出现错误,否则上述操作将永远运行。您可能希望程序在某个点停止。您需要多路传输输入。相关系统调用为或ppoll或pselect。读取非常有用。您需要多路传输输入。相关系统调用为或ppoll或pselect。读取时很有用。一次读取和写入一个字符效率很低。根据C标准的§6.5.3.4-1,sizeofchar被保证为1。我看不出还有什么其他方法可以读取行而不是字符,因为长度将是可变的。读取数据块而不是行或字符。更新了我的答案,使之更加明确。一次读写一个字符效率低下。根据C标准的§6.5.3.4-1,sizeofchar被保证为1。我看不出还有什么其他方法可以读取行而不是字符,因为长度将是可变的。读取数据块而不是行或字符。更新了我的答案,使其更加明确。我认为没有必要将管道设置为非阻塞。您应该在每个管道上使用FD_ISSET宏来查看哪些管道有数据,只需点击那个按钮。@ams:将管道设置为非阻塞是防止读取调用被阻塞的必要条件。如果不不不必要地调用read,则不需要这样做-select的全部要点是它会告诉您哪个管道有数据。@ams:我不是指从没有等待数据的文件描述符中读取数据。很少有读取会阻塞的情况,即使没有不必要的读取。。。。用一个read调用来替换read循环将减少出现这种情况的可能性,但不会完全消除这种情况。我认为没有必要将管道设置为非阻塞。您应该在每个管道上使用FD_ISSET宏来查看哪些管道有数据,只需点击那个按钮。@ams:将管道设置为非阻塞是防止读取调用被阻塞的必要条件。如果不不不必要地调用read,则不需要这样做-select的全部要点是它会告诉您哪个管道有数据。@ams:我不是指从没有等待数据的文件描述符中读取数据。很少有读取会阻塞的情况,即使没有不必要的读取。。。。用一个read调用替换read循环将减少出现错误的可能性,但不会完全消除错误。