前言
Python的代码的执行是由Python虚拟机(又名解释器主循环)进行控制的。Python在设计时就是这样考虑的,在主循环中同时只能有一个控制线程在执行,就像单核CPU系统中的多进程一样。内存中可以有许多程序,但是在任意给定时刻只能有一个程序在运行。同理,尽管Python解释器中可以运行多个线程,但是在任意给定时刻只有一个线程会被解释器执行。
对Python虚拟机的访问是由全局解释锁(GIL)控制的。这个锁就是用来保证同时只能有一个线程运行的。在多线程环境中,Python虚拟机将按下面所述的方式执行。
- 设置GIL。
- 切换进一个线程去运行。
- 执行下面操作之一。
- 指定数量的字节码指令
- 线程主动让出控制权
- 把线程设置回睡眠状态
- 解锁GIL
- 重复上述步骤
在讨论普通的GIL之前,有一点要强调的是GIL只会影响到那些严重依赖CPU的程序(比如计算型的)。 如果你的程序大部分只会设计到I/O,比如网络交互,那么使用多线程就很合适, 因为它们大部分时间都在等待。
对于CPU依赖型的程序,你要搞清楚计算的特点。把性能瓶颈优化到关键的部分,如对数组的操作用NumPy这样的模块就非常的高效。
theading模块
是最常用的多线程模块,老的thread模块就不用看了
有Thread、Lock、Rock、Condition、Event、Semaphore、BoundedSemphore、Timer、Barrier等一系列可用对象
Thread对象
基本代码
|
|
Thread启动后不能用ctrl+c
手动终止的解决方法
这里引用别人描述
爬虫作为子线程运行时不受键盘中断信号影响,Ctrl-C无法终止整个爬虫运行。另外的一个场景是多线程压力测试,需要提前终止的情况下,Ctrl-C依旧不能终止整个程序。除了简单粗暴的使用kill命令强行终止之外,本文将给出一个简单可行的解决方案。
可能,python2 和python3对于异常的处理逻辑不一致,2中所有的异常在主线程真正退出时才被捕获。