从控制台读取时,Linux相当于WaitForSingleObject?

Irb*_*bis 1 c linux winapi

在我的 Windows 应用程序中,我WaitForSingleObject()在从控制台读取时使用:

HANDLE h = (void*)GetStdHandle(STD_INPUT_HANDLE);
char buf[512] = { 0 };
DWORD r = 0;

if (WaitForSingleObject(h, 3000) == WAIT_OBJECT_0)
{
    ReadConsole(h, buf, 512, &r, 0);
}
Run Code Online (Sandbox Code Playgroud)

看起来,为了将上面的代码移植到 Linux,我必须实现一个条件等待。我将如何实施?在读取某些字符之前,如何检查它们是否已写入控制台?

Ian*_*ott 5

与 Windows 代码非常相似的代码如下:

    int h = STDIN_FILENO;
    char buf[512] = { 0 };
    ssize_t r = 0;
    struct pollfd fds[1];
    int ret;

    fds[0].fd = h;
    fds[0].events = POLLIN;
    ret = poll(fds, 1, 3000);
    if (ret > 0 && (fds[0].revents & POLLIN) != 0)
    {
        r = read(h, buf, 512);
    }
Run Code Online (Sandbox Code Playgroud)

#include <unistd.h>这使用来自和 的声明#include <poll.h>

poll()函数等待指定文件描述符上的各种指定事件,并具有以毫秒为单位指定的超时。超时值-1允许poll()无限期等待(类似于Windows 上INFINITEin 调用的超时值WaitForSingleObject())。成功完成后,它返回一个正值,指示pollfd具有待处理事件的结构数量(即具有非零.revents成员)。(也有可能在成员中报告一些.revents未在.events成员中要求的特殊事件。)超时时,它返回 0。出错时,它返回-1errno(由 定义#include <errno.h>)包含错误号。

成员中的特殊事件.revents包括POLLERR(指示文件描述符上发生了错误)、POLLHUP(指示文件描述符上出现“挂起”状态)以及POLLNVAL(指示指定的文件描述符无效)。

函数read()调用可能会无限期地阻塞,但如果文件描述符不是常规文件,并且文件描述符已准备好读取(已在调用结果中进行了测试poll()),则通常不会阻塞。(也可以使用该函数将底层文件置于非阻塞模式fcntl(),在这种情况下,如果尚未准备好,read()则返回-1并设置errno为。不关心非阻塞模式。)成功时返回的数量读取的字节数可能小于请求的数量。(对于特殊文件,如果有一些可用数据但少于请求的数量,它通常会返回可用的数据,而不是无限期地阻塞以尝试读取请求的数量。)返回值应被视为“结束”文件”的条件。(对于某些设备(例如终端),“文件结束”条件仅仅是一个建议,并且是终端上某些特殊输入序列的结果。)失败时返回并设置为错误号。EAGAINpoll()read()0read()-1errno

对于来自终端的交互式输入,还需要考虑其他事项,例如终端的“termios”设置。其中,这些控制着来自终端的输入准备好被读取时的条件。在默认的“规范”模式下,输入将逐行准备好。在“非规范”模式下,输入准备就绪取决于控制最小字符数和/或自上一个read()或上一个接收到的字符以来经过的时间的其他参数。“termios”设置可以通过tcgetattr()tcsetattr()声明的函数进行查询和更改#include <termios.h>,且仅适用于终端设备。(isatty()由 声明的函数#include <unistd.h>可用于测试文件描述符是否引用终端。)


注意:poll()您可能还会遇到更古老的select()pselect()用于相同目的的等待文件描述符上的事件。它们将超时参数作为指向struct timeval(for select()) 的指针或指向struct timespec(for pselect()) 的指针传递。select()可能会更新 来struct timeval指示返回时还剩多少时间(但pselect() 修改其struct timespec)。