1

当我在 OS X 中编译这段代码时:

#include <unistd.h>
#include <iostream>
#include <memory>
#include <aio.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;

int main(int, char*[])
{
    const int iBufSize = 1<<20;
    unique_ptr<char[]> pBuffer(new char[iBufSize]);
    int iRet;

    int iOpts = fcntl(STDIN_FILENO, F_GETFL);
    cout << "GETFL Before: " << iOpts << endl;
    fcntl(STDIN_FILENO, F_SETFL, iOpts & ~O_NONBLOCK);
    iOpts = fcntl(STDIN_FILENO, F_GETFL);
    cout << "GETFL After: " << iOpts << endl;

    aiocb cb = {0};
    cb.aio_fildes = STDIN_FILENO;
    cb.aio_buf = pBuffer.get();
    cb.aio_nbytes = iBufSize;
    iRet = aio_read(&cb);
    cout << "aio_read retuned " << iRet << endl;
    cout << "errno = " << strerror(errno) << "(" << errno << ")" << endl;
    return 0;
}

用 g++ 编译它,然后像这样执行它:

echo "Hello" | ./aio_read\ demo

它返回:

GETFL Before: 0
GETFL After: 0
aio_read retuned -1
errno = Resource temporarily unavailable(35)

为什么?如果我在没有前面的情况下运行它,echo "Hello" |它会按预期工作。此外,fcntl 调用不需要引起问题,但它们确实表明 STDIN 没有O_NONBLOCK设置。

4

1 回答 1

0

如果我在没有前面的情况下运行它,echo "Hello" |它会按预期工作。

七年半之后,这对我来说也是个问题。

不幸的是,在撰写本文时,OS X 不支持管道上的 aio。因此,您的管道输入因 EAGAIN 失败,但aoi_read在其他标准输入输入(终端< /dev/null、普通文件)上成功。

至少有一个开源项目也遇到了这个限制

于 2022-01-10T18:20:48.443 回答