我正在尝试在一个侦听器进程中处理4个不同的命名unix管道。
我尝试使用select来处理管道的文件描述符。我以非阻塞模式打开所有命名管道
我遇到了问题,选择完全没有睡觉。继续在循环中运行。
我不知道我的代码中的问题在哪里。我在下面粘贴了我的代码。
始终保留select select中的最后一个文件描述符,尽管它没有管道中的内容。
请说明代码中有什么问题?
diag_fd = open(DIAG_PIPE , O_RDONLY | O_NONBLOCK );
while(1)
{
FD_ZERO(&fds);
FD_SET(cp_fd, &fds);
FD_SET(diag_fd, &fds);
FD_SET(err_fd, &fds);
FD_SET(perf_fd, &fds);
if (select(cp_fd+1, &fds, NULL, NULL, &tv) < 0)
{
perror("select");
return ;
}
for (int fd = diag_fd; fd <= cp_fd; fd++)
{
if (FD_ISSET(fd, &fds))
{
if (fd == diag_fd)
{
ProcessDiagLogs();
}
else if (fd == err_fd)
{
ProcessErrLogs();
}
else if (fd == perf_fd)
{
ProcessPerfLogs();
}
else if (fd == cp_fd)
{
ProcessCPLogs();
}
}
}
ProcessDiagLogs()
do
{
if ((num = read(diag_fd, s, BUF_LENGTH)) == -1)
perror("read");
else {
s[num] = '\0';
fputs(s, filed);
fflush(filed);
}
} while (num > 0);
答案 0 :(得分:4)
select()允许您监视一个或多个文件描述符,等待其中一个变为“就绪”,即数据可用。
在您的情况下,const struct timespec *timeout
,tv
指定超时期限,或者他选择的日志如何等待数据直到它返回(这表现得像一个睡眠)。如果超时为0,则select立即返回,如果它是NULL
,它可以无限期地阻塞。
你没有在你的代码中显示你如何初始化电视,但我猜它是零,因此你看到的行为。
尝试在调用select之前初始化超时,看看是否有帮助:
tv.tv_sec = 1;//or any other value you see fit
tv.tv_usec= 0;