Wal*_*alt 2 c linux macos posix named-pipes
下面的程序在 OS X 下运行良好,但在 linux 中不运行。它继续循环遍历 perror("read error") 行,读取缓冲区中没有字节,并且 EWOULDBLOCK 不是 errno (errno=0);
在 OS X 中,程序按预期工作,即它从三个命名管道中读取数据,并将其中任何一个中的任何数据打印到控制台。
#include <sys/types.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int readPipe(int fd)
{
ssize_t bytes;
size_t total_bytes = 0;
char buffer[100*1024];
printf("\nReading pipe descriptor # %d\n",fd);
for(;;) {
bytes = read(fd, buffer, sizeof(buffer));
if (bytes > 0) {
total_bytes += (size_t)bytes;
printf("%s", buffer);
}
else {
if (errno == EWOULDBLOCK) {
break; // recieve buffer is empty so return to main loop
}
else {
perror("read error");
return EXIT_FAILURE;
}
}
}
return EXIT_SUCCESS;
}
int main(int argc, char* argv[])
{
int fd_a, fd_b, fd_c; // file descriptors for each pipe
int nfd; // select() return value
fd_set read_fds; // file descriptor read flags
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 10000;
// create pipes to monitor (if they don't already exist)
system("mkfifo /tmp/PIPE_A");
system("mkfifo /tmp/PIPE_B");
system("mkfifo /tmp/PIPE_C");
system("chmod 666 /tmp/PIPE_*");
// open file descriptors of named pipes to watch
fd_a = open("/tmp/PIPE_A", O_RDONLY | O_NONBLOCK); // the O_RDWR flag is undefined on a FIFO.
if (fd_a == -1) {
perror("open error");
return EXIT_FAILURE;
}
fd_b = open("/tmp/PIPE_B", O_RDONLY | O_NONBLOCK);
if (fd_b == -1) {
perror("open error");
return EXIT_FAILURE;
}
fd_c = open("/tmp/PIPE_C", O_RDONLY | O_NONBLOCK);
if (fd_c == -1) {
perror("open error");
return EXIT_FAILURE;
}
// check for new data in each of the pipes
for(;;)
{
// clear fds read flags
FD_ZERO(&read_fds);
// PIPE_A
FD_SET(fd_a, &read_fds);
nfd = select(fd_a+1, &read_fds, NULL, NULL, &tv);
if (nfd != 0) {
if (nfd == -1) {
perror("select error");
return EXIT_FAILURE;
}
if (FD_ISSET(fd_a, &read_fds)) {
readPipe(fd_a);
}
}
// PIPE_B
FD_SET(fd_b, &read_fds);
nfd = select(fd_b+1, &read_fds, NULL, NULL, &tv);
if (nfd != 0) {
if (nfd == -1) {
perror("select error");
return EXIT_FAILURE;
}
if (FD_ISSET(fd_b, &read_fds)){
readPipe(fd_b);
}
}
// PIPE_C
FD_SET(fd_c, &read_fds);
nfd = select(fd_c+1, &read_fds, NULL, NULL, &tv);
if (nfd != 0) {
if (nfd == -1) {
perror("select error");
return EXIT_FAILURE;
}
if (FD_ISSET(fd_c, &read_fds)){
readPipe(fd_c);
}
}
}
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
read 可以返回 0 是允许的(并且是预期的)。这意味着管道正在返回 EOF。您没有处理这种情况。的内容errno无关紧要,除非调用失败并返回 -1。
for (;;)
{
bytes = read(fd, buffer, sizeof(buffer));
if (bytes > 0)
{
total_bytes += (size_t)bytes;
printf("%s", buffer);
}
if (bytes == 0)
return //something appropriate
if (bytes == -1)
{
if (errno == EWOULDBLOCK)
break; // recieve buffer is empty so return to main loop
else
{
perror("read error");
return EXIT_FAILURE;
}
}
}
Run Code Online (Sandbox Code Playgroud)
您正在努力返回不同的代码,但在main.
另外,这 3 条select语句又是怎么回事?我认为这在上一个问题中已经解决了。
编辑
for (;;)
{
// clear fds read flags
FD_ZERO(&read_fds);
FD_SET(fd_a, &read_fds);
FD_SET(fd_b, &read_fds);
FD_SET(fd_c, &read_fds);
tv.tv_sec = 0;
tv.tv_usec = 10000;
nfd = select(fd_c + 1, &read_fds, NULL, NULL, &tv);
if (nfd == 0) //timeout - continue or do something else for a bit
continue;
if (nfd == -1)
{
perror("select error");
return EXIT_FAILURE;
}
if (FD_ISSET(fd_a, &read_fds))
readPipe(fd_a);
if (FD_ISSET(fd_b, &read_fds))
readPipe(fd_b);
if (FD_ISSET(fd_c, &read_fds))
readPipe(fd_c);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4529 次 |
| 最近记录: |