如何检查标准输入是否仍然打开而不阻塞? [英] How to check if stdin is still opened without blocking?

查看:32
本文介绍了如何检查标准输入是否仍然打开而不阻塞?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要用纯 C 编写的程序在标准输入关闭时停止执行.

I need my program written in pure C to stop execution when stdin is closed.

在程序主循环中完成了无限期的工作,我无法在那里使用阻塞检查(如 getc())(没有数据应该到达标准输入 - 它只是停留开放时间未知).

There is indefinite work done in program main cycle, and there is no way I can use blocking checks (like getc()) there (no data is supposed to arrive on stdin - it just stays opened for unknown time).

我打算使用所描述的功能来实现托管在 inetd、xinetd 或其类似物中的网络守护程序 - 它应该在连接保持打开时在 stdout 上发出数据,并在连接关闭时正确完成工作.现在我的程序被托管服务杀死,因为它在连接终止后不会停止.

I intend to use described functionality in realization of network daemon hosted in inetd, xinetd or their analogs - it should emit data on stdout while connection stays opened and correctly finish work when it closes. Now my program is killed by hosting service as it won't stop after connection termination.

我想知道将 O_NONBLOCK 标志应用于 stdin 描述符的 fctntl() 是否允许我在非阻塞中使用 read() 函数模式?我应该以某种方式使用 select() 吗?

I wonder if fctntl() with O_NONBLOCK flag applied to stdin descriptor would allow me to use read() function in non-blocking mode? Should I use select() somehow?

附言数据不应该,但可能会到达标准输入.一种非阻塞读出的方法将是这个问题的答案.

P.S. The data is not supposed but might arrive to stdin. A way of non-blocking readout woould be an answer for the question.

推荐答案

select() 完全符合您的要求:表示对文件描述符(文件、套接字等)不会阻塞.

select() does exactly what you want: signal that an operation (read, in this case) on a file descriptor (file, socket, whatever) will not block.

#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;
}

您现在可以在使用前检查文件描述符,例如为了清空文件描述符:

You can now check a file descriptor before use, for instance in order to empty the file descriptor:

void empty_fd(int fd) {
    char buffer[1024];
    while (is_ready(fd)) {
        read(fd, buffer, sizeof(buffer));
    }
}

在你的情况下,使用 fileno(stdin) 来获取 stdin 的文件描述符:

In your case, use fileno(stdin) to get the file descriptor of stdin:

if (is_ready(fileno(stdin))) {
    /* read stuff from stdin will not block */
}

这篇关于如何检查标准输入是否仍然打开而不阻塞?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆