我对套接字比对常规文件更感兴趣,但基本上我想知道一个进程是否可以将套接字“视为”阻塞,而另一个进程可以将其视为非阻塞。我猜是的,内核根据系统调用中使用的选项来处理所有这些。
我想这更多是关于 Unix 域套接字而不是 TCP 套接字,因为我不认为 2 个不同的进程可以使用相同的 TCP 套接字(但我可能是错的)
我对套接字比对常规文件更感兴趣,但基本上我想知道一个进程是否可以将套接字“视为”阻塞,而另一个进程可以将其视为非阻塞。我猜是的,内核根据系统调用中使用的选项来处理所有这些。
我想这更多是关于 Unix 域套接字而不是 TCP 套接字,因为我不认为 2 个不同的进程可以使用相同的 TCP 套接字(但我可能是错的)
你猜错了。
唯一可以更改的每个文件描述符的属性是close
fcntl(F_SETFD)
-FD_CLOEXEC
on-exec 标志。所有其他属性要么是每个文件对象(POSIX 术语中的“打开文件描述”——可以用 更改
fcntl(F_SETFL)
),要么是每个 inode。fcntl(F_SETFL, | O_NONBLOCK)
使用或使用设置非阻塞标志ioctl(FIONBIO)
将影响引用该打开文件的所有文件描述符。也没有办法使文件非阻塞仅用于读取或写入。这远非理想——您还可以参考StackOverflow 上的此问答,尤其是 lkml讨论的链接,该链接讨论了以某种方式修复它失败的尝试。
请注意,常规文件基本上是非阻塞的——它们上的 a
poll(2)
orselect(2)
将立即返回。如果你只对套接字感兴趣,你应该使用or
send(2)
标志而不是or 。与您所说的相反,套接字文件描述符可以在进程之间共享,无论它的系列/协议/选项是什么。这也适用于监听套接字。recv(2)
MSG_DONTWAIT
read(2)
write(2)
将进程中的一个文件描述符更改为阻塞或非阻塞不会影响同一进程或其他进程的其他文件描述符。O_NONBLOCK 是文件描述符的属性,而不是文件或套接字的属性。我记错了。为了避免这种情况,必须打开文件两次(而不是 dup/fork)或创建两次套接字。并且不同的进程可以使用同一个 TCP 套接字。看到这个问题。如果它们正确同步,它们甚至可以写入同一个套接字。