python多线程以及线程同步
多线程基础知识
- python创建多线程主要依靠threading库
import threading |
- 线程的创建使用
Thread()函数,提供的参数为线程的函数指针和函数的参数(必须为可迭代的对象)
def task(num): |
- 线程的开始使用
start(),使用join()回收线程
# 多线程 |
多线程时间测试
- 线程执行任务为控制台输出的
import threading |

- 可见,多线程用时还更多一些
多线程执行不涉及IO的操作(比如加法)
import threading |
- 输出结果为

- 可见,单线程比多线程的优势更明显了
原因
你会发现多线程比单线程花费的时间还要更多,这是因为GIL的原因。
GIL的全称是Global Interpreter Lock(全局解释器锁),Python最初的设计理念在于,为了解决多线程之间数据完整性和状态同步的问题,设计为在任意时刻只能由一个线程在解释器中运行。因此Python中的多线程是表面上的多线程(同一时刻只有一个线程),不是真正的多线程。
但是如果是因为GIL的原因,就说多线程无用是不对的,对于IO密集的程序,多线程是要比单线程快的。
python线程同步
- python线程同步具有一些与C类似的机制,比如各种锁和获取、释放锁等等
- 参考链接
同步锁Lock
lock = threading.Lock() |
用于保护临界区
由于
threading.Lock()对象中实现了enter__()与__exit()方法,故我们可以使用with语句进行上下文管理形式的加锁解锁操作
with lock: |
RLock() 递归锁
递归锁是同步锁的一个升级版本,在同步锁的基础上可以做到连续重复使用多次acquire()后再重复使用多次release()的操作,但是一定要注意加锁次数和解锁次数必须一致,否则也将引发死锁现象。
其他部分类似,不再详细赘述
Condition() 条件锁
条件锁是在递归锁的基础上增加了能够暂停线程运行的功能。并且我们可以使用wait()与notify()来控制线程执行的个数。
注意:条件锁可以自由设定一次放行几个线程。

import threading |
- 注意,上面的代码中的线程在使用
acquire()获取锁之后,进入了休眠状态(也就是wait()),然后等待锁的notify()函数唤醒相应数量的正在休眠的进程
Event() 事件锁
事件锁是基于条件锁来做的,它与条件锁的区别在于一次只能放行全部,不能放行任意个数量的子线程继续运行。
我们可以将事件锁看为红绿灯,当红灯时所有子线程都暂停运行,并进入“等待”状态,当绿灯时所有子线程都恢复“运行”。

import threading |
- 不能使用
with语句进行调用
Semaphore() 信号量锁
信号量锁也是根据条件锁来做的,它与条件锁和事件锁的区别如下:
- 条件锁:一次可以放行任意个处于“等待”状态的线程
- 事件锁:一次可以放行全部的处于“等待”状态的线程
- 信号量锁:通过规定,成批的放行特定个处于“上锁”状态的线程

import threading |
- 注意调用
Semaphore()初始化的时候传递参数指定同时能够放行的线程数量 - 也可以使用
with语句
import threading |