美文网首页
Linux 里进程阻塞原理

Linux 里进程阻塞原理

作者: 爱健身的兔子 | 来源:发表于2021-03-08 10:06 被阅读0次

    误区一:进程阻塞消耗 CPU 资源

    我以前以为进程阻塞是不好的,比如 NIO 里 Socket socket = serverSocket.accept(); 会一直阻塞直到连接到来。程序要一直等待不能往下运行,感觉上是一个不好的事情。

    其实,对于 CPU 来说,在这个进程阻塞的时候完全可以去跑别的程序。而对于上面的程序来说,这个阻塞也是有益的,它提供了一个等待的时间让程序能够等待连接到来。

    你可能会想,进程阻塞了之后,CPU 会立马跑别的进程吗?CPU 还会回来尝试跑这个进程吗?这些问题都会影响 CPU 性能。

    你需要了解 CPU 的时间片轮转机制解决第一个问题。

    CPU 的时间片轮转机制

    单核 CPU 在某一时刻只能跑一个进程。但小时候用的单核 CPU 的电脑一样可以“同时”运行多个程序,为什么?这是因为操作系统提供了一种CPU时间片轮转机制。

    时间片轮转调度是一种最古老、最简单、最公平且使用最广的算法。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。

    如果在时间片结束时进程还在运行,则CPU使用权将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。

    由于切换的时间很短(大概为5毫秒),切片时间也很短(一般为100毫秒),以人的反应结果就是感觉多个程序同时运行,且没有停顿(切换的时间和在别的切片上的时间)。当然如果我们开多了程序,也会很直观的感觉卡,玩游戏的时候会把其它软件关掉,也有这个道理。

    知道了 CPU 的时间片轮转机制,你就知道了程序阻塞了它的进程之后,CPU 会立马跑别的进程。

    但是你想知道CPU 还会不会回来尝试跑这个进程,你需要知道工作队列和等待队列。

    工作队列和等待队列

    如下图所示,Linux 内核空间里会维持一个工作队列,因为时间片轮转机制,系统会在进程A、B、C等多个进程间切换着跑。


    假如现在进程 A 里跑的程序有一个对象执行了某个方法将当前进程阻塞了,内核会立刻将进程A从工作队列中移除,同时在该对象里创建等待队列,并新建一个引用指向进程A。如下图:


    从图中可以看到,进程A被排在了工作队列之外,不受系统调度了,这就是我们常说的被操作系统“挂起”。
    这也提现了阻塞和挂起的关系。阻塞是人为安排的,让你程序走到这里阻塞。而阻塞的实现方式是系统将进程挂起。

    当这个对象受到某种“刺激”(某事件触发)之后, 操作系统将该对象等待队列上的进程重新放回到工作队列上就绪,等待时间片轮转到该进程。

    所以,我们可以知道了上面第二个问题的答案,操作系统不会去尝试运行被阻塞的进程,而是由对象去等待某种“刺激”。

    补充一点:这个“刺激”有的时候是说来就来的。操作系统在跑进程时,会有优先级的区别。而硬件产生的信号,CPU 收到后往往会直接中断正在执行的程序,去做出响应,执行中断程序,这个优先级是很高的。这也很好理解,我们的鼠标、键盘一有动作,计算机会立即给出反应,就是这个道理。

    误区二:进程阻塞不会消耗系统资源

    这两个误区对新手来说容易混淆,尤其是你在看完上面的文字之后容易进入这样的误区。

    其实也很简单,系统资源不仅包括 CPU,还有内存、磁盘IO等。进程阻塞不会消耗 CPU 资源,当然不代表不会消耗系统资源。

    而且进程正式系统进行资源分配的最小单位。进程虽然阻塞了,但仍然存在,存在就会占用系统资源。

    原文链接:https://blog.csdn.net/weixin_44367006/article/details/101637239

    相关文章

      网友评论

          本文标题:Linux 里进程阻塞原理

          本文链接:https://www.haomeiwen.com/subject/tlcpqltx.html