编码不易,转载请注意出处!
python多线程虽然有GIL管着,在IO密集型任务的时候,还是可以用的。
本文给出一个很简单的线程不安全的示例,说明一个事情:凡是共享的资源,都要自己加锁控制,不要以为python的每一行脚本都是原子操作,虽然python自定的确定义了一些原子操作,但是不要去依赖,如果哪一天python解释器修改了内部机制,你的代码就会崩溃;对于共享资源,无论有几个修改线程,加把锁更安全。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| from threading import Thread, Lock
number = 0
def target(): global number for _ in range(1000000): number += 1
thread_01 = Thread(target=target) thread_02 = Thread(target=target) thread_01.start() thread_02.start()
thread_01.join() thread_02.join()
print(number)
|
两个线程,并发对一个全局变量进行+1操作,我们预期的结果是2000000,但是不是,每一次运行都不是,而且还不一样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| $ python thread_not_safe.py 1391219
$ python thread_not_safe.py 1241460
$ python thread_not_safe.py 1210578
$ python thread_not_safe.py 1221867
$ python thread_not_safe.py 1136912
|
加锁方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| from threading import Thread, Lock
number = 0 mutex = Lock()
def target(): global number for _ in range(1000000): mutex.acquire() number += 1 mutex.release()
thread_01 = Thread(target=target) thread_02 = Thread(target=target) thread_01.start() thread_02.start()
thread_01.join() thread_02.join()
print(number)
|
这样每次运行代码得到的结果都是2000000!