当从控制台阅读时,Linux是否等效于WaitForSingleObject?

omvjsjqw  于 2023-08-03  发布在  Linux
关注(0)|答案(1)|浏览(101)

在我的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);
}

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

hrirmatl

hrirmatl1#

与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);
    }

字符串
这使用了来自#include <unistd.h>#include <poll.h>的声明。
poll()函数等待指定文件描述符上的各种指定事件,并有一个以毫秒为单位的超时。-1的超时值允许poll()无限期等待(类似于Windows上调用WaitForSingleObject()时的超时值INFINITE)。成功完成后,它返回一个正值,表示有事件挂起的pollfd结构的数量(即有一个非零的.revents成员)。(也有可能在.revents成员中报告一些特殊事件,而这些事件在.events成员中没有被请求。)超时时,它返回0。如果出现错误,则返回-1errno(由#include <errno.h>定义)包含错误号。
.revents成员中的特殊事件包括POLLERR(表示文件描述符发生错误)、POLLHUP(表示文件描述符处于“挂起”状态)和POLLNVAL(表示指定的文件描述符无效)。
read()函数调用可能会无限期阻塞,但如果文件描述符不是常规文件,则如果文件描述符已准备好读取(已在poll()调用的结果中测试过),则通常不会阻塞。(也可以使用fcntl()函数将底层文件置于非阻塞模式,在这种情况下,read()将返回-1,并将errno设置为EAGAIN,如果它没有准备好。poll()不关心非阻塞模式。)成功时,read()返回读取的字节数,该字节数可能小于请求的数量。(对于特殊文件,如果有一些数据可用,但少于请求的数量,它通常会返回可用的数据,而不是无限期地阻塞以尝试和读取请求的数量。)0的返回值应被视为“文件结束”条件。(对于某些设备,例如终端,“文件结束”条件只是一个建议,是终端上某些特殊输入序列的结果。)失败时,read()返回-1并将errno设置为错误号。
对于来自终端的交互式输入,还有其他事情要考虑,例如终端的“termios”设置。除此之外,这些控制来自终端的输入何时准备好被读取的条件。在默认的“规范”模式下,输入将逐行就绪。在“非规范”模式下,输入是否就绪取决于其他参数,这些参数控制最小字符数和/或自上一个read()或上一个接收到的字符以来经过的时间。“termios”设置可以通过#include <termios.h>声明的tcgetattr()tcsetattr()函数进行查询和更改,并且只能在终端设备上工作。(#include <unistd.h>声明的isatty()函数可用于测试文件描述符是否引用终端。
注意:除了poll(),你还可能会遇到更古老的select()pselect(),它们用于等待文件描述符上的事件。它们将timeout参数作为指向struct timeval的指针(对于select())或指向struct timespec的指针(对于pselect())传递。select()可以更新struct timeval,以指示返回时还剩多少时间(但pselect() * 不会 * 修改其struct timespec)。

相关问题