掌握了Linux I/O机制,才能真的明白“什么是多线程”

用户进程向 CPU 发起 read 请求,CPU 向 DMA 发起 I/O 请求,DMA 再向磁盘发起 I/O 请求。这里的 DMA 全称为 Direct Memory Access,你可以简单理解为 CPU 内存和磁盘之间的代理。

磁盘向 CPU 发起 I/O 中断,CPU 拷贝数据,先是内核态 buffer,再到用户态 buffer。

用户进程从内核态切回用户态,阻塞状态结束,程序继续执行,直到结束。

上述流程中,用户进程在拿到磁盘数据之前,只能原地等待,也就是处于阻塞状态,这个时候 CPU 就空闲了,显然造成了 CPU 资源的浪费。这个时候如果在该进程内拉起另一个线程 T,那么 T 就可以见缝插针,在主线程等待数据的过程中, 把 CPU 的闲置资源利用起来,岂不美哉!这就是多线程技术的由来。

总有一些概念把人绕晕 — 同步/异步、阻塞/非阻塞

在学习多线程技术的过程中,总有一些概念时不时蹦出来,比如同步/异步、阻塞/非阻塞,如果你是一位并发领域的高手,那么这些都是小儿科。如果你是一位初学者,那么你很可能陷入其中,不能自拔,从而最终放弃。接下来,我们尝试终结这个问题,带你爬出这个坑。

举个例子:

假如某一天你要去银行办理某项业务,到了银行,首先要凭身份证取个号。取完号之后,你发现这天人特别多,于是你就要等,等着被叫号。在等待的过程中,你可以有以下几个选择:

选择 1: 啥也不干,死盯着银行的液晶显示屏,等到出现你的号码时,你赶紧起身直奔柜台,银行叫号系统甚至还没来得及叫你的号。那么,在这段时间内,你就处于阻塞状态,而且你和银行叫号系统之间的关系是同步的。“阻塞”好理解,因为你啥也没干嘛!“同步”怎么理解呢?因为你和银行叫号系统的步调要保持一致,当显示屏上出现你的号时,你就得立马去柜台办业务,而银行自动广播喊你的功能对你来说,是没必要的。

选择 2:你还是啥也不干,但是你坐在座位上开始冥想,做着白日梦。因为你知道,轮到你的时候,银行叫号系统会广播叫你的。听到广播后,你再起身去柜台也不迟。那么在这段时间内,你还是处于阻塞状态。而你和银行叫号系统之间的关系是异步的,因为你不用再关注屏幕上滚动的号码,轮到你的时候,自然它会广播告诉你。

选择 3:对于一个聪明的人,显然不会坐在那傻等或者胡思乱想了。这时候,你拿起手机,决定打一把王者荣耀,打游戏的过程中,你还是时不时瞄一眼显示屏,等看到你的号码时,立马起身去柜台。那么这段时间内,你就处于非阻塞状态,因为你还干其他事了呀。但你和银行叫号系统间的关系还是同步的。

选择 4:如果你打算专心致志地玩一把王者荣耀,不想坑队友。那么你就等着广播叫你就可以了。那么这段时间内,你就处于非阻塞的状态,而且和银行叫号系统之间的关系还是异步的。

【声明】:芜湖站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

相关文章