多线程面试题汇总
一、多线程
1、线程的生命周期

1、线程的创建:t=threading.Thread()
2、就绪状态:已经获得了除CPU之外的其他资源,正在参与调度,等待被执行,当调度完成之后,立即运行
3、启动状态:获得了CPU时间片段,正在运行
4、等待\阻塞状态:遇到time.sleep()时,会阻塞,暂时不参与调度,等待事件发生
5、中止状态:线程运行结束,run函数运行结束,等待系统回收其线程资源。
2、线程的创建(函数创建)


3、线程的创建(使用类)
t=MyThread(name=s[i]) 创建线程,里面的参数代表线程的名字,如果不传,系统会默认有一个名字

4、守护线程
当我们在程序运行中,执行一个主线程,如果主线程又创建一个子线程,主线程和子线程就分兵两路,分别运行,那么当主线程完成想退出时,会检验子线程是否完成。如果子线程未完成,则主线程会等待子线程完成后再退出。但是有时候我们需要的是只要主线程完成了,不管子线程是否完成,都要和主线程—起退出,这时就可以用setDaemon方法

输出结果:线程2还没有完整的执行完毕,遇到守护线程就终止执行了。

t.setDaemon(True) 当前的子线程设置为守护线程
守护线程:随着主线程的终止而终止,不管当前主线程下有多少子线程没有执行完毕,都会终。
二、全局解释器锁
1、GIL锁不是python的特点。而是cpython的特点。
每个线程在执行的时候都需要先获取GIL,保证同一时刻只有一个线程可以执行代码,即同一时刻只有一个线程使用CPU。在CPython中,每一个Python线程执行前都需要去获得GIL锁,获得该锁的线程才可以执行,没有获得的只能等待,当具有GIL锁的线程运行完成后,其他等待的线程就会去争夺GIL锁,这就造成了,在Python中使用多线程,但同一时刻下依旧只有一个线程在运行,所以Python多线程其实并不是「并行」的,而是「并发」。
1、使用单线程实现累加到500000000
import time,threading
def task(n):
sum=0
while sum<n:
sum+=1
print(f'最后累加哦结果为:{
sum}')
if __name__ == '__main__':
# 单线程
start=time.time()
task(500000000)
end=time.time()
print(f'单线程结束后,一共运行的时间为:{
end-start}')

2、使用多线程实现累加到500000000
import time,threading
def task(n):
sum=0
while sum<n:
sum+=1
print(f'最后累加哦结果为:{
sum}')
if __name__ == '__main__':
# 多线程
start = time.time()
t1=threading.Thread(target=task,args=(250000000,))
t2=threading.Thread(target=task,args=(250000000,))
t1.start()
t2.start()
t1.join()
t2.join()
end=time.time()
print(f'单线程结束后,一共运行的时间为:{
end-start}') # todo 15.777813196182251

发现问题:两个线程同时执行并不能比单个线程的执行快
由此发现:CPU密集型(计算密集型)任务采用多线程执行并不能提高计算速度
3、总结
GIL解决办法:
- 使用其他语言写的python解析器(不推荐,还是用python官方的CPython好)
- JPython、pypy
- 不使用多线程,使用多进程-进程里面加协程实现多任务来充分利用多核CPU(推荐)
- 即使存在GIL,在有IO等待操作的程序中,还是多线程快;当然没有资源等待的还是使用单线程快(科学计算、累加等等)
但是需要注意的是线程有了GIL后并不意味着使用python多线程时不需要考虑线程安全,GIL的存在是为了方便使用C语言CPython解释器的编写者,而顶层使用python时依旧要考虑线程安全。
三、线程安全
当多个线程同时访问一个对象时,不管如何计算,如果调用这个对象的行为都可以获得正确的结果,那就称这个对象时线程安全的。如果出现了“脏数据”。则线程不安全。
脏数据:产生脏数据的原因是,当一个线程在对数据进行修改时,修改到一半时另一个线程读取了未经修改的数据并进行修改。
如何避免脏数据的产生呢?一个办法就是用join方法,即先让一个线程执行完毕再执行另一个线
程。但这样的本质是把多线程变成了单线程,失去了多线程的意义。另一个办法就是用线程锁。
1、多线程之数据混乱问题


但是当我把累加次数设置小,就不会出现数据混乱问题

数据混乱的原因:
cpu分成多个时间片段,启动10线程,分配10


2014

被折叠的 条评论
为什么被折叠?



