前言
这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题
于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。
微信小程序搜索:Python面试宝典
或可关注原创个人博客:https://lienze.tech
也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习
线程
线程被称为轻量级进程,是CPU执行的最小单位
一般线程由一个父进程诞生,可以认为是在一个主进程中并行运行的一些**‘迷你进程’**
- 线程的属性
一个进程中的各个线程和主进程共享同一片数据空间
相比进程而言,线程间的通信及数据共享更加容易
线程一般以并发方式进行,而且线程之间共享数据,所以可能会导致在多核心CPU下,一个数据被多个线程同时使用,使数据混淆所以还会有各种各样的同步原语来解决这样的问题,保证数据资源的稳定
主进程死亡,其中全部子线程都会死亡
线程也有自己的身份标识,但是只在当前的进程上下文中有意义,这个标示常称为TID
GIL
Python
代码的执行是由Python
虚拟机进行控制;进行分配内存,系统管理等等
在设计之初,这些大佬们考虑,同一时间只能由一个线程在执行;类似单核CPU
系统中的多进程一样,同时只能有一个进程被CPU
处理
这就引出了一个叫做GIL
全局解释器锁的东西;多线程执环境下,一个线程在执行前,解释器首先会为这个线程设置GIL
锁,只有被加锁的线程才会被CPU
执行处理,但是这也就导致,在多核处理器下,其他线程只能是看着这个持有唯一锁的线程工作;线程工作结束,释放锁
GIL
锁的存在,导致python
的多线程不是实际的并发行为,只是简单的io切换和cpu时间片切换;不过好消息是,关于线程全局解释性锁GIL
的问题,已经在各个版本逐步完善ceval.c
线程模块
Python3中,支持线程的有两个模块:_thread
和threading
;
_thread
提供了基本的线程创建和锁支持
threading
提供了更全面,更高级的线程管理、所以都推荐使用threading
模块
虽然Python
中的线程有GIL
锁,但是在进行IO
密集型工作时,IO
等待时候,GIL
锁会被释放,其他线程继续持锁工作,此外线程在进行cpu
上下文切换时所需的损耗要远小于进程工作切换
- 注意:cpu密集选择多进程,io密集选择多线程
threading
import threading
t = Thread(target=None, name=None, args=(), kwargs=None)
'''
target: 线程任务函数
name: 线程名
args: 线程任务函数的参数,以位置参数形式传递
kwargs: 线程任务函数的操作,以命名参数形式传递
'''
t.name # 线程名
t.start() # 开启线程
t.join(time=None) # 阻塞等待线程执行结束
# 参数指定时,将指定阻塞多少秒,只有在daemon值True时生效
t.daemon = True # 设置守护线程
# 设置该属性True之后,如果没有join阻塞等待线程结束,主进程会直接退出,并且线程结束
t.getName() # 设置线程名称
t.setName() # 获取线程名称
t.isAlive() t.is_alive() # 判断线程是否激活
- 代码示例
from threading import Thread,Lock,currentThread
import time
def work():
time.sleep(1)
print(currentThread().name)
return 100
def main():
t1 = Thread(target=work)
t1.daemon = True
t1.start() # 启动且不回收
print('over')
if __name__ == '__main__':
main()