【操作系统专题】进程与线程进阶问题
本问题对应的项目链接:高频题回答模版训练
PS:下面这些问题,相对有难度一些,一般都是通过追问的方式来问的
1、AB共享内存通信,A new一块内存与B通信,A异常退出,B还能访问那块内存吗 为什么?
2、线程切换的时机?给线程分配时间片,操作系统怎么知道时间片用完了?线程切换 一定会引起内核态和用户态的切换吗?
3、单核情况下,为啥多线程能够比单线程效率好?
4、多线程效率一定比单线程要好吗?
5、居然多线程或者单线程各有优劣势,那你可以举几个适合多线程或者单线程的例子吗?
共以下 2 个回答
1、AB共享内存通信,A new一块内存与B通信,A异常退出,B还能访问那块内存吗 为什么?
是可以的,因为共享内存本身独立于 A,B 进程,是由操作系统来分配和管理的。如果 A 中途异常退出,但没有销毁这块共享内存,是不会影响 B 对共享内存继续读或者写的。
3、单核情况下,为啥多线程能够比单线程效率好?
如果是 CPU 密集型作业,在单核情况下,多线程的效率是不如单线程的。因为多线程会带来额外的线程上下文切换开销,单线程只需一直运行即可。而且如果作业量很小,使用多线程带来的线程创建开销和上下文切换开销是大于多线程本身的效率提高的。
但如果是 IO 密集型作业,线程在进行 IO 操作时就不得不阻塞,此时 CPU 是闲着的,也就是 CPU 没有充分得到利用。此时就可以引入多线程,将任务拆分给多个线程去完成,当某个线程因进行 IO 而阻塞时,CPU 还可以处理其它线程任务,这个情况下多线程是比单线程效率高的。
5、居然多线程或者单线程各有优劣势,那你可以举几个适合多线程或者单线程的例子吗?
在对视频或者图像进行处理,压缩时,由于每个像素可以独立处理,可以使用多线程来加快处理速度。还有对于高并发网络服务器而言,引入多线程可以同时处理多个客户端请求,能很大程度提高响应速度和吞吐量。
对于一些简单的,执行时间短的脚本就没必要进入多线程。也可以通过一些机制与单线程配合,最大程度发挥单线程的优点,比如 Redis 等等。
1、AB共享内存通信,A new一块内存与B通信,A异常退出,B还能访问那块内存吗 为什么?
是可以的,因为共享内存本身独立于 A,B 进程,是由操作系统来分配和管理的。并且 A,B 在使用共享内存通信时,都需要先分别 ”连接“ 上这块共享内存。如果 A 中途异常退出,但没有销毁这块共享内存,是不会影响 B 对共享内存继续读或者写的。
2、线程切换的时机?给线程分配时间片,操作系统怎么知道时间片用完了?线程切换 一定会引起内核态和用户态的切换吗?
大多数情况下会在时间片耗尽时进行线程切换。
操作系统主要通过一些硬件的支持来实现时间片。具体的,操作系统会设置一个定时器,以固定的时间间隔产生时钟中断。时间片的大小就可以用时钟中断的间隔来体现,每次时钟中断发生时,操作系统会中断当前正在执行的线程,将控制权交还给操作系统内核,从而实线程切换。
不一定,首先线程切换和调度只有拥有最高权限的内核才可以完成。从这个角度来说,如果线程当前处于用户态,如果要发生线程切换,确实是要先进入内核态,整个过程有用户态和内核态之间的切换。但如果线程当前已经处于内核态了,也一样可能遇到中断等等发生线程切换,此时就直接在内核态进行切换,不需要在切换到用户态了。总之,线程切换和状态切换没有直接关系,只不过线程切换一般都交给内核完成,是否发生状态切换应于线程此时所在的状态有关。
3、单核情况下,为啥多线程能够比单线程效率好?
这个需要看情况,如果是 CPU 密集型作业,在单核情况下,多线程的效率是不如单线程的。因为多线程会带来额外的线程上下文切换开销,单线程只需一直运行即可。
但如果是 IO 密集型作业,线程在进行 IO 操作时就不得不阻塞,此时 CPU 是闲着的,也就是 CPU 没有充分得到利用。此时就可以引入多线程,将任务拆分给多个线程去完成,当某个线程因进行 IO 而阻塞时,CPU 还可以处理其它线程任务,这个情况下多线程是比单线程效率高的。进一步,作业中 IO 操作的时间越长,多线程带来的效率提升就越高。
4、多线程效率一定比单线程要好吗?
不一定,除了上边说的情况,还有就是如果作业量很小,使用多线程带来的线程创建开销和上下文切换开销是大于多线程本身的效率提高的。我做过一个实验,对两个变量进行累加和累减。并发情况将累加和累减交给两个线程完成,串行情况则在一个线程内完成两个操作,实验结果为在数据量在十万以下串行执行时间是小于并行的,数据量在百万以上并行的效率才与串行拉开差距。
5、既然多线程或者单线程各有优劣势,那你可以举几个适合多线程或者单线程的例子吗?
在对视频或者图像进行处理,压缩时,由于每个像素可以独立处理,可以使用多线程来加快处理速度。还有对于高并发网络服务器而言,引入多线程可以同时处理多个客户端请求,能很大程度提高响应速度和吞吐量。
对于一些简单的,执行时间短的脚本就没必要进入多线程。也可以通过一些机制与单线程配合,最大程度发挥单线程的优点,比如 Redis 等等(感觉单线程的运用能扯到 Redis 上)。