文件描述符标志和函数

File Descriptor flags and functions

我想知道当我在函数中使用给定的 file_desO_NONBLOCK 标志会发生什么。它是否保留设置的标志?

如果不是,我是否应该在 function 中重置它?还有其他办法吗?

main()
{
    int file_des;

    fcntl(file_des, F_SETFD, O_NONBLOCK);
    function(file_des);

}

function(int file_des)
{
    //do something with file_des
    //What happens with the O_NONBLOCK flag?
}

文件描述符是进程范围的。在函数或线程中使用时,它们总是以相同的方式工作。这种方式由 状态标志 控制。 Linux中有five status flags:

  • O_APPEND:导致所有写入发生在文件末尾,忽略文件位置。

  • O_ASYNC:可读或可写时产生信号;仅适用于终端、伪终端、套接字、管道和 FIFO。 (我确实记得它也可用于某些字符设备,但我没有验证哪些设备(如果有的话);手册页没有说明。)

  • O_DIRECT:跳过 I/O 的页面缓存。复杂,有很多限制;除非在非常有限的特殊情况下,否则不要使用。

  • O_NOATIME: 不更新上次访问时间。

  • O_NONBLOCK:非阻塞I/O。当数据不是立即可用或无法立即发送时,不是等待(阻塞),而是 return 一个简短的计数。如果无法发送或接收任何内容,则 read()/write() 等 return -1 与 errno == EWOULDBLOCK
    O_NONBLOCK对普通文件或块设备没有影响

您可以通过使用 fcntl(fd, F_SETFL, flags) 设置新的状态标志集来修改它们,零个或多个标志通过“或”运算在一起。 (要禁用所有,请使用零。)

fcntl(fd, F_SETFD, dflags) 设置了一组 文件描述符标志 。目前,只有一个这样的标志,O_CLOEXEC,它会导致描述符在 execve() 或其他 exec 系列函数成功时自动关闭(包括 popen() 和所有其他 fork 和执行一个新进程)。但是,O_CLOEXEC 通常用作 open() 调用的标志,以避免 window 与另一个在两者之间执行 fork() 的线程竞争。

当您使用 open(filename, flags)open(filename, flags, mode) 时,flags 参数是访问模式(O_RDONLYO_WRONLYO_RDWR; 必须使用一个),文件创建标志(包括文件描述符标志)和文件状态标志,或在一起。 (除了O_ASYNC,不能在open()时指定,必须在fcntl(fd, F_SETFL, flags | O_ASYNC)之后设置。)