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