Python 线程threading

Python多线程适用于I/O密集型
GIL的全称是Global Interpreter Lock(全局解释器锁),为了数据安全,GIL保证同一时间只能有一个线程拿到数据。所以,在python中,同时只能执行一个线程。而IO密集型,多线程能够有效提升效率(单线程下有IO操作会进行IO等待,造成不必要的时间浪费,而开启多线程能在线程A等待时,自动切换到线程B,可以不浪费CPU的资源,从而能提升程序执行效率)。所以python多线程对IO密集型代码比较友好。

而CPU密集型(各种循环处理、计算等等),由于计算工作多,计时器很快就会达到阈值,然后触发GIL的释放与再竞争(多个线程来回切换当然是需要消耗资源的),所以python多线程对CPU密集型代码并不友好。

Python多线程的工作过程


Python在使用多线程的时候,调用的是c语言的原生线程。

拿到公共数据
申请gil
python解释器调用os原生线程
os操作cpu执行运算
当该线程执行时间到后,无论运算是否已经执行完,gil都被要求释放
由其他进程重复上面的过程
等其他进程执行完后,又会切换到之前的线程(从他记录的上下文继续执行),整个过程是每个线程执行自己的运算,当执行时间到就进行切换(context switch)。
构造函数
threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)


调用这个构造函数时,必需带有关键字参数。参数如下:

group 应该为 None;为了日后扩展 ThreadGroup 类实现而保留。
target 是用于 run() 方法调用的可调用对象。默认是 None,表示不需要调用任何方法。
name 是线程名称。默认情况下,由 "Thread-N" 格式构成一个唯一的名称,其中 N 是小的十进制数。多个线程可以赋予相同的名称。
args 是用于调用目标函数的参数元组。默认是 ()。
kwargs 是用于调用目标函数的关键字参数字典。默认是 {}。
daemon 参数如果不是 None,将显式地设置该线程是否为守护模式。 如果是 None (默认值),线程将继承当前线程的守护模式属性。3.3 版及以上才具有该属性。
一定要在调用 start() 前设置好,不然会抛出 RuntimeError 。初始值继承于创建线程;主线程不是守护线程,因此主线程创建的所有线程默认都是 daemon = False。

当没有存活的非守护线程时,整个Python程序才会退出。

如果子类型重载了构造函数,它一定要确保在做任何事前,先发起调用基类构造器(Thread.__init__())。
线程函数
start()
开始线程活动。

它在一个线程里最多只能被调用一次。它安排对象的 run() 方法在一个独立的控制进程中调用。

如果同一个线程对象中调用这个方法的次数大于一次,会抛出 RuntimeError 。

join(timeout=None)
        等待,直到线程终结。这会阻塞调用这个方法的线程,直到被调用 join() 的线程终结 -- 不管是正常终结还是抛出未处理异常 -- 或者直到发生超时,超时选项是可选的。

当 timeout 参数存在而且不是 None 时,它应该是一个用于指定操

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值