Unix/Linux套接字中的阻塞模式是如何工作的?

4
阻塞模式是否会将特定任务置于“进程等待”状态?我认为非阻塞套接字需要用户显式地实现“忙等待”或“自旋锁”。或者说,阻塞模式套接字只是内核隐式实现忙等待的一种方式。
在诸如信号量/互斥锁/监视器之类的锁定机制中,通常通过将任务推入阻塞状态来实现锁定。我认为如果锁定可以实现这样的事情,那么套接字锁定也可能通过同样的方式实现。
我不确定,但我认为轮询不是一种有效的方法,尤其是对于内核而言,因为内核总是忙于处理众多任务。
谢谢。
3个回答

10
不,阻塞套接字是由内核实现的。该进程处于非执行状态,不消耗任何 CPU 时间。内核可以运行其他任务直到某些外部活动引起它唤醒该任务。例如,网络卡的硬件中断通知内核有数据需要读取。内核读取数据并将其推送到网络堆栈中,最终唤醒应用程序以处理数据。定时器也是这样,但使用定时器中断。内核可能实际上正在轮询硬件,但不必如此...这完全取决于硬件的设计。

@Chris - "放置"是什么意思?一个进程必须处于其中一种状态。你所说的“放置”,是指等待状态吗?但这正是我在问题中问到的。我自己也不知道,因为我认为轮询不是一种有效的方式,特别是对于内核来说,尤其是当内核总是忙于处理如此多的任务时。 - Vivek Sharma
1
当在阻塞套接字操作上被阻塞时,进程将处于睡眠状态(在 ps 命令的 STAT 列中显示为“S”)。 - mark4o
我认为Chris的意思是操作系统会将其放在等待输入的进程列表中。直到它接收到发送到绑定到正在读取的套接字的端口的数据包,该进程才会被操作系统唤醒。 - cygil
正如Cygil所说...具体情况取决于操作系统,但任务会进入某种“休眠”状态,在此状态下不会被执行,并且在等待输入的任务列表中。一旦输入可用,任务就会被唤醒并标记为准备好执行。 - Chris Arguin

1

0

基于我从网络/书籍和提供的答案中学到的知识,我将尝试简明扼要地阐述。

默认情况下,所有套接字都是阻塞的。这意味着当我们发出一个无法立即完成的套接字调用时,我们的进程会被置于睡眠状态,等待条件成熟。《UNIX网络编程》-- 第435页

睡眠是通过将进程置于等待/阻塞状态来实现的。调度程序检查解除阻塞进程的条件,当阻塞进程获得CPU时,即调度程序将其轮到时。在这种情况下,响应能力取决于调度程序的时间分辨率。

因此,阻塞调用不是内核中“忙等待”或“自旋锁”的隐式实现。

是的,大多数实现的锁定底层机制相同。将进程置于阻塞/等待状态。

当然,轮询效率不高,这就是为什么不使用轮询实现阻塞的原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接