【发布时间】:2013-10-19 00:03:21
【问题描述】:
“阻塞系统调用”是什么意思?
在我的操作系统课程中,我们正在学习多线程编程。当我在教科书中读到“当线程进行阻塞系统调用时,它可以允许另一个线程运行”时,我不确定是什么意思
【问题讨论】:
标签: c multithreading operating-system system-calls
“阻塞系统调用”是什么意思?
在我的操作系统课程中,我们正在学习多线程编程。当我在教科书中读到“当线程进行阻塞系统调用时,它可以允许另一个线程运行”时,我不确定是什么意思
【问题讨论】:
标签: c multithreading operating-system system-calls
阻塞系统调用是必须等到操作完成的系统调用。 read() 将是一个很好的例子 - 如果没有输入准备好,它会坐在那里等到一些输入(当然,前提是你没有将它设置为非阻塞,在这种情况下它不会是阻塞系统调用)。显然,当一个线程正在等待阻塞系统调用时,另一个线程可以停止做其他事情。
【讨论】:
对于阻塞系统调用,调用者在系统调用返回之前不能做任何事情。如果系统调用可能很长(例如涉及文件 IO 或网络 IO),这可能是一件坏事(例如,想象一个沮丧的用户在应用程序中敲击“取消”按钮,但由于该线程被阻塞等待来自未到达的网络的数据包)。为了解决这个问题(在等待阻塞系统调用返回时做有用的工作),您可以使用线程 - 当一个线程被阻塞时,另一个线程可以继续做有用的工作。
替代方案是非阻塞系统调用。在这种情况下,系统调用(几乎)立即返回。对于冗长的系统调用,系统调用的结果要么稍后发送给调用者(例如,作为某种事件、消息或信号),要么稍后由调用者轮询。这允许您有一个线程同时等待许多不同的冗长系统调用完成;并避免了线程的麻烦(以及锁定、竞争条件、线程切换的开销等)。但是,这也增加了获取和处理系统调用结果的麻烦。
(几乎总是)可以围绕阻塞系统调用编写非阻塞包装器;包装器产生一个线程并(几乎)立即返回,产生的线程执行阻塞系统调用,并将系统调用的结果发送给原始调用者或将它们存储在原始调用者可以轮询的地方。
也可以(几乎总是)围绕非阻塞系统调用编写阻塞包装器;包装器执行系统调用并在返回之前等待结果。
【讨论】:
我建议阅读这段非常短的文本: http://files.mkgnu.net/files/upstare/UPSTARE_RELEASE_0-12-8/manual/html-multi/x755.html 特别是你可以阅读为什么阻塞系统调用可能是线程的问题,而不仅仅是并发进程:
这对于多线程应用程序尤其成问题,因为 一个线程阻塞系统调用可能会无限期延迟更新 另一个线程的代码。
希望对你有帮助。
【讨论】: