服务器之家:专注于服务器技术及软件下载分享
分类导航

Linux|Centos|Ubuntu|系统进程|Fedora|注册表|Bios|Solaris|Windows7|Windows10|Windows11|windows server|

服务器之家 - 服务器系统 - Linux - 理解了Linux I/O机制,才能真的明白“什么是多线程”

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

2020-11-09 22:52今日头条xiaoxiao落木 Linux

如果问你“为什么多线程可以提高程序运行效率?”,想必你会说“计算机并行执行任务啊,当然效率高!” 这显然不是一个内行该给出的答案。要知道,一个 CPU 在任何时间点上只能干一件事情啊,如果执行了指令 A,就不能执行指

你真的了解多线程吗?

如果问你“为什么多线程可以提高程序运行效率?”,想必你会说“计算机并行执行任务啊,当然效率高!” 这显然不是一个内行该给出的答案。要知道,一个 CPU 在任何时间点上只能干一件事情啊,如果执行了指令 A,就不能执行指令 B 了,何来并行呢?想要真正理解多线程,必须得先弄清 Linux 中的 I/O 机制。

什么是 Linux I/O ?

一般指文件读取/写入、网卡读取/写入。不管是文件 I/O,还是网卡 I/O,其准备数据速度都远远低于 CPU 处理数据的速度 。磁盘读数据,毫秒级别,最慢。其次是网卡,微秒。再就是内存,纳秒,最快的是缓存。

下图显示了一个 Linux 进程(只有一个主线程)的执行过程:

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

好了,总结一下:

所谓阻塞就是请求者发起读取数据的函数调用时,当数据还没准备好,这时如果函数一直在等待返回结果,就是阻塞;反之如果函数即刻返回,继续执行后面的动作就是非阻塞。

在 I/O 模型里,如果请求方从发起请求到数据最后准备好的这一段过程中都需要自己参与,那么这种我们称为同步请求;反之,如果应用发送完指令后就不再参与过程了,只需要等待最终完成结果的通知,那么这就属于异步。

哦,对了。上述选择 2 你也可以认为是 选择 4,因为你只要等待银行广播叫你就可以呀,做白日梦也可以认为是在干自己的事嘛!

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

再谈多线程

所谓多线程,就是多个线程在一个进程里同时运行,它们之间可以是协作的关系,一起完成某个共同的任务,也可以各干各的事。不管协作,还是单干,总有一个问题绕不开:“CPU 的资源怎么分配?”多线程之间争夺资源的过程可以认为是一种“零和博弈”,线程 A 抢夺的资源多,那么线程 B 得到的资源必然就少了嘛!一般来说,用户只会关心 CPU 总的利用率,这个值越大越好,而不用关注具体每个线程得到的计算资源是多是少。

延伸 · 阅读

精彩推荐
  • Linuxlinux top命令详解

    linux top命令详解

    这篇文章主要介绍了linux top命令详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    sparkdev5622022-03-01
  • Linux在Linux系统中创建新的亚马逊AWS访问密钥的方法

    在Linux系统中创建新的亚马逊AWS访问密钥的方法

    如何在Linux系统中创建新的亚马逊AWS访问密钥?我在配置一个需要访问我的亚马逊AWS帐号的应用时被要求提供AWS访问密钥ID和秘密访问密钥,我怎样创建一个...

    Linux教程网6182019-10-30
  • Linuxssh 登录很慢该如何解决

    ssh 登录很慢该如何解决

    这篇文章主要介绍了ssh 登录很慢该如何解决的相关资料,这里提供了两种方法,DNS反向解析及关闭ssh的gssapi认证的解决办法,需要的朋友可以参考下...

    linuxeye9922021-12-16
  • Linuxlinux驱动程序开发详细介绍

    linux驱动程序开发详细介绍

    前提,一般来说内核代码的错误可能会引起一个用户进程的死亡,或者整个系统的瘫痪,更严重的后果,可能导致磁盘损伤~因此建议最好有一台实验机进行...

    Linux教程网5392019-12-17
  • Linux将 Linux 终端与 Nautilus 文件管理器结合起来

    将 Linux 终端与 Nautilus 文件管理器结合起来

    Nautilus 是 GNOME 桌面环境中的图形化文件浏览器。你可以使用它来访问和管理系统中的文件和文件夹。 尽管并非所有人都喜欢使用终端来管理文件和目录,...

    未知812023-08-08
  • Linux理解 Linux/Unix 登录脚本的技巧

    理解 Linux/Unix 登录脚本的技巧

    有一些常见的情况,例如从Debian的包管理程序到Iaas的管理中,很多任务需要设置环境变量才能正常运行。 有时,程序通常只需要在 登陆时运行一次,例如...

    未知1042023-05-12
  • LinuxLinux系统下无法卸载挂载的目录怎么办?

    Linux系统下无法卸载挂载的目录怎么办?

    我们在日常运维中经常性会遇到需要进行磁盘的扩容、卸载、挂载等操作,但是有时候这个系统上跑的应用并没有停止或者有其他的运维同事在操作这个目...

    今日头条10302020-12-30
  • Linuxlinux设置tomcat自启动的方法

    linux设置tomcat自启动的方法

    这篇文章主要介绍了linux设置tomcat自启动的方法,需要的朋友可以参考下...

    Linux教程网8512021-10-10