“阻塞系统调用”是什么意思?

31

"阻塞系统调用"的意思是什么?

在我的操作系统课程中,我们正在学习多线程编程。当我在教材中读到“当一个线程进行阻塞系统调用时,它可以允许另一个线程运行”,我不确定其含义。

4个回答

31

阻塞式系统调用是一种必须等待操作完成的调用。 read() 是一个很好的例子 - 如果没有输入准备好,它会一直等待,直到有输入(当然,前提是你没有将其设置为非阻塞模式,否则它将不是一个阻塞式系统调用)。显然,当一个线程在等待阻塞式系统调用时,另一个线程可以做其他事情。


这意味着当用户线程使用此阻塞系统调用时,它将等待(此线程被阻塞),另一个用户线程可以映射到之前映射的内核线程吗? - sam
1
我不知道你正在学习什么课程或者它想要告诉你什么,但我想应该是这样的。一个多对一的多线程模型将几个用户线程与单个内核线程相关联。如果该内核线程处于阻塞系统调用状态,则与其关联的所有用户线程也必须等待。这在一对一模型中并不成立,因为所有用户线程都有自己的内核线程,所以如果一个内核线程被阻塞,另一个内核线程可以做其他事情。 - Crowman
我有相同的问题。如果它是一对多模型,并且用户线程想要进行阻塞系统调用,那么所有其他线程都必须停止吗?(只有内核线程才能进行系统调用吗?) - codeconscious
@PaulGriffiths 阻塞调用与yield点有什么关系?(在nesC论文中,它们之间存在一种隐含的关系,即“我们需要禁止原子部分中的阻塞调用,并将阻塞调用视为任务调度的yield点。”) - Novemberland
1
@Novemberland:一个yield point是一个方便的地方(例如,它没有对共享资源的独占访问权),在这个地方任务有机会自愿放弃执行。通常情况下,任务希望在超过其时间片之前就这样做。由于阻塞系统调用可能会被阻塞很长时间,潜在地远远超过任务的时间片,在一个任务自愿放弃控制的系统中,进入一个阻塞系统调用将是一个理想的yield point。 - Crowman
一个多对一的线程模型可以(而且应该)将阻塞调用映射到不会阻止进度的替代方案。但是要正确实现相当复杂。 - curiousguy

24
对于阻塞式系统调用,调用者在系统调用返回前无法执行任何操作。如果系统调用可能很长(例如涉及文件IO或网络IO),这可能是一个坏事情(例如想象一个沮丧的用户在应用程序中猛击“取消”按钮,因为该线程被阻塞等待来自网络的数据包而无响应)。为了解决这个问题(在等待阻塞式系统调用返回时处理有用的工作),可以使用线程——当一个线程被阻塞时,其他线程可以继续执行有用的工作。
另一种选择是非阻塞式系统调用。在这种情况下,系统调用会立即(几乎)返回。对于长时间运行的系统调用,系统调用的结果稍后发送给调用者(例如作为某种事件、消息或信号),或者由调用者稍后轮询。这使您可以有一个单独的线程同时等待许多不同的长时间运行的系统调用完成;避免了线程(和锁定、竞争条件、线程切换的开销等)的麻烦。然而,它也增加了获取和处理系统调用结果的麻烦。
(几乎总是)可以编写一个非阻塞式封装器,将阻塞式系统调用包装成非阻塞式系统调用;其中封装器生成一个线程并几乎立即返回,生成的线程执行阻塞式系统调用,并将系统调用的结果发送给原始调用者或存储在原始调用者可以轮询的位置。
(几乎总是)也可以编写一个阻塞式封装器,将非阻塞式系统调用包装成阻塞式系统调用;其中封装器执行系统调用并等待结果,然后才返回。

非阻塞系统调用和分裂阶段操作之间有什么关系?第二个只是第一个的一个小子集吗?还有其他与非阻塞系统调用相关的操作吗?或者它们是同一件事吗?提前致谢! - Novemberland

4

-1
阻塞系统调用是指任何进程请求系统提供某项服务,但该服务当前不可用的系统调用。因此,特定的系统调用会阻塞该进程。
如果您想在多线程上下文中清楚地表达它,可以通过以下链接了解...

您的回答可以通过添加更多支持性信息来改进。请编辑以添加更多细节,例如引用或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - Community

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