Bas*_*evs 9 c stdin stream nonblocking
我需要用纯C编写的程序在stdin关闭时停止执行.
在程序主循环中完成了不确定的工作,并且我无法在那里使用阻塞检查(例如getc())(没有数据应该到达stdin - 它只是在未知时间保持打开状态).
我打算在实现inetd,xinetd或其类似物中托管的网络守护程序时使用所描述的功能 - 它应该在连接保持打开时在stdout上发出数据,并在关闭时正确完成工作.现在我的程序被托管服务杀死,因为它在连接终止后不会停止.
我想知道fctntl()将O_NONBLOCK标志应用于stdin描述符是否允许我read()在非阻塞模式下使用函数?我应该select()以某种方式使用?
PS数据不是假定的,但可能会到达stdin.一种非阻塞读数的方式应该是问题的答案.
select()完全按照你的意愿执行:表示文件描述符(文件,套接字等)上的操作(在本例中为read)不会阻塞.
#include <stdio.h>
#include <sys/select.h>
int is_ready(int fd) {
fd_set fdset;
struct timeval timeout;
int ret;
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
timeout.tv_sec = 0;
timeout.tv_usec = 1;
//int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout);
return select(fd+1, &fdset, NULL, NULL, &timeout) == 1 ? 1 : 0;
}
Run Code Online (Sandbox Code Playgroud)
您现在可以在使用前检查文件描述符,例如为了清空文件描述符:
void empty_fd(int fd) {
char buffer[1024];
while (is_ready(fd)) {
read(fd, buffer, sizeof(buffer));
}
}
Run Code Online (Sandbox Code Playgroud)
在您的情况下,使用fileno(stdin)来获取stdin的文件描述符:
if (is_ready(fileno(stdin))) {
/* read stuff from stdin will not block */
}
Run Code Online (Sandbox Code Playgroud)