烤面筋的第五场

举报
看,未来 发表于 2021/03/08 23:37:03 2021/03/08
【摘要】 文章目录 Question One: 有了进程,为什么还要有线程?进程的不足:线程的优势: Question Two:请你来说一说协程相对于线程,协程的优势 Question Three: 请你说一下多进程和多线程的使用场景Question Four:请问单核机器上写多线程程序,是否需要考虑加锁,为什么?Question Five:请你讲述一下互斥锁(mut...

在这里插入图片描述

Question One: 有了进程,为什么还要有线程?

那肯定是进程不够用了嘛,所以线程才出来补缺补漏了。

进程的不足:

1、进程在执行的过程中如果阻塞,整个进程就会挂起。
2、启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,总的来说就是耗资甚大。
3、据统计,一个进程的开销大约是一个线程开销的30倍左右。
4、对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过进程间通信的方式进行,这种方式不仅费时,而且很不方便。

线程的优势:

1、线程是一种非常"节俭"的多任务操作方式。
2、由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其他线程所用,这不仅快捷,而且方便。
3、操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。
4、一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序才会利于理解和修改。


Question Two:请你来说一说协程

说真的,对于协程,还停留在初步了解的状态,因为还没深入了解C++该如何去操作协程。

协程,英文Coroutines,是一种比线程更加轻量级的存在。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。
在这里插入图片描述

子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。

所以子程序调用是通过栈实现的,一个线程就是执行一个子程序。

子程序调用总是一个入口,一次返回,调用顺序是明确的。而协程的调用和子程序不同。

协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。

注意,在一个子程序中中断,去执行其他子程序,不是函数调用,有点类似CPU的中断。比如子程序A、B:

def A(): print '1' print '2' print '3'

def B(): print 'x' print 'y' print 'z'

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

假设由协程执行,在执行A的过程中,可以随时中断,去执行B,B也可能在执行过程中中断再去执行A,结果可能是:

1 x 2 y 3 z

  
 
  • 1

但是在A中是没有调用B的,所以协程的调用比函数调用理解起来要难一些。


相对于线程,协程的优势

最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。

第二大优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。

因为协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。


Question Three: 请你说一下多进程和多线程的使用场景

多进程模型的优势是CPU,因此适用于CPU密集型的工作场景。

多线程模型主要优势为线程间切换代价较小,因此适用于I/O密集型的工作场景。


Question Four:请问单核机器上写多线程程序,是否需要考虑加锁,为什么?

仍然需要线程锁。在单核机器上的多线程程序,仍然存在线程同步的问题。在抢占式操作系统中,通常为每个线程分配一个时间片,当某个线程时间片耗尽时,操作系统会将其挂起,然后运行另一个线程。如果这两个线程共享某些数据,不使用线程锁的前提下,可能会导致共享数据修改引起冲突。


Question Five:请你讲述一下互斥锁(mutex)机制,以及互斥锁和读写锁的区别

我就不搬运了,链接跳转吧锁种


Question Six:请你说一说死锁发生的条件以及如何解决死锁

这个还是要搬运一下的,因为上次模拟面试的时候我给卡壳儿了。

说白了,就是竞态。
多个进程所共享的资源不足,引起它们对资源的竞争而产生死锁
-竞争可剥夺和非剥夺性资源
-竞争非剥夺性资源

进程运行过程中,请求和释放资源的顺序不当,而导致进程死锁
-进程推进顺序合法
-进程推进顺序非法


产生死锁的四个必要条件

互斥条件
进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占有

请求和保持条件
当进程因请求资源而阻塞时,对已获得的资源保持不放

不剥夺条件
进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放

环路等待条件
在发生死锁时必然存在一个进程—资源的环形链

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

破坏死锁的方法

预防死锁、避免死、检测死锁、解除死锁

当然,防范于未然是首要的。
如果死锁真发生了,那就只能:
-剥夺资源
-撤销进程


Question Seven:游戏服务器应该为每个用户开辟一个线程还是一个进程,为什么?

游戏服务器应该为每个用户开辟一个进程。因为同一进程间的线程会相互影响,一个线程死掉会影响其他线程,从而导致进程崩溃。因此为了保证不同用户之间不会相互影响,应该为每个用户开辟一个进程


Question Eight:怎样确定当前线程是繁忙还是阻塞?

用ps命令。

文章来源: blog.csdn.net,作者:看,未来,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq_43762191/article/details/114359263

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。