C 从命名管道读取
我必须编写一个程序来监视两个命名管道,并打印通过其中一个管道发送的信息 当其中一个管道的写入端关闭时,程序将检测到此情况并再次关闭和打开管道 这是我到目前为止写的:C 从命名管道读取,c,pipe,named-pipes,C,Pipe,Named Pipes,我必须编写一个程序来监视两个命名管道,并打印通过其中一个管道发送的信息 当其中一个管道的写入端关闭时,程序将检测到此情况并再次关闭和打开管道 这是我到目前为止写的: #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #incl
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define BUF_SIZE 200
int
main(void)
{
fd_set rfds;
struct timeval tv;
int retval;
ssize_t n_read;
char buf[BUF_SIZE];
/* Open pipes */
int tuberia1_fd = open("tuberia1",O_RDONLY);
int tuberia2_fd = open("tuberia2",O_RDONLY);
while(1){
/* Watch stdin (fd 0) to see when it has input. */
FD_ZERO(&rfds);
FD_SET(0, &rfds);
/* Wait for an indefinite amount of time. */
tv.tv_sec = 0;
tv.tv_usec = 0;
retval = select(2, &rfds, NULL, NULL, &tv);
/* Don't rely on the value of tv now! */
if (retval == -1)
perror("select()");
exit(EXIT_FAILURE);
if(FD_ISSET(tuberia1_fd, &rfds)){
n_read = read(tuberia1_fd, &buf, BUF_SIZE);
if (n_read == 0){
close(tuberia1_fd);
tuberia1_fd = open("tuberia1", O_RDONLY);
}else{
buf[n_read] = '\0';
printf("tuberia1: %s", buf);
}
} else if (FD_ISSET(tuberia2_fd, &rfds)){
n_read = read(tuberia2_fd, &buf, BUF_SIZE);
if (n_read == 0){
close(tuberia2_fd);
tuberia2_fd = open("tuberia2", O_RDONLY);
}else{
buf[n_read] = '\0';
printf("tuberia2: %s", buf);
}
}
}
}
它仍然不起作用。在GDB下运行它表明程序永远不会超过第一个
open
您需要对您实际感兴趣的文件描述符使用FD\u SET
,即tuberia1\u FD
和tuberia2\u FD
所以有点像
while (1) {
FD_ZERO(&rfds);
FD_SET(tuberia1_fd, &rfds);
FD_SET(tuberia2_fd, &rfds);
int max;
if (tuberia1_fd > tuberia2_fd) {
max = tuberia1_fd;
} else {
max = tuberia2_fd;
}
tv.tv_sec = 0;
tv.tv_usec = 0;
retval = select(max + 1, &rfds, NULL, NULL, &tv);
如果您在调试器中运行程序,我很有信心您会看到执行
echo
命令会导致您的程序通过第一个open()
,而在第二个上被阻塞。捕捉得好!然而,我已经解决了这个问题,但仍然不起作用。您能否进一步阐述一下您所说的“不起作用”
?你能在调试器中一步一步地检查代码,找到if失败或执行意外操作的点吗?当我使用GBD运行它时,程序在第一次打开调用时会卡住
while (1) {
FD_ZERO(&rfds);
FD_SET(tuberia1_fd, &rfds);
FD_SET(tuberia2_fd, &rfds);
int max;
if (tuberia1_fd > tuberia2_fd) {
max = tuberia1_fd;
} else {
max = tuberia2_fd;
}
tv.tv_sec = 0;
tv.tv_usec = 0;
retval = select(max + 1, &rfds, NULL, NULL, &tv);