Skip to content

Commit 6e21674

Browse files
committed
多线程锁机制
1 parent d885a42 commit 6e21674

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed

threading_lock.py

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# encoding: utf-8
2+
__author__ = 'zhanghe'
3+
4+
import time
5+
import threading
6+
7+
# 假定这是你的银行存款:
8+
balance = 0
9+
lock = threading.Lock()
10+
11+
12+
def change_it(n):
13+
# 先存后取,结果应该为0:
14+
global balance
15+
balance = balance + n
16+
balance = balance - n
17+
18+
19+
def run_thread(n):
20+
for i in range(100000):
21+
change_it(n)
22+
23+
24+
def run_thread_lock(n):
25+
for i in range(100000):
26+
# 先要获取锁:
27+
lock.acquire()
28+
try:
29+
# 放心地改吧:
30+
change_it(n)
31+
finally:
32+
# 改完了一定要释放锁:
33+
lock.release()
34+
35+
36+
def run_without_lock():
37+
"""
38+
不带锁的主程序
39+
:return:
40+
"""
41+
start_time = time.time()
42+
t1 = threading.Thread(target=run_thread, args=(5,))
43+
t2 = threading.Thread(target=run_thread, args=(8,))
44+
t1.start()
45+
t2.start()
46+
t1.join()
47+
t2.join()
48+
end_time = time.time()
49+
print end_time - start_time
50+
print balance
51+
52+
53+
def run_with_lock():
54+
"""
55+
带锁的主程序
56+
:return:
57+
"""
58+
start_time = time.time()
59+
t1 = threading.Thread(target=run_thread_lock, args=(5,))
60+
t2 = threading.Thread(target=run_thread_lock, args=(8,))
61+
t1.start()
62+
t2.start()
63+
t1.join()
64+
t2.join()
65+
end_time = time.time()
66+
print end_time - start_time
67+
print balance
68+
69+
if __name__ == '__main__':
70+
# 这是银行账户修改的简单例子,以下分别测试不加锁与加锁的运行情况
71+
run_without_lock()
72+
# run_with_lock()
73+
74+
75+
'''
76+
run_without_lock()运行结果:
77+
0.209647893906
78+
8(不固定)
79+
80+
run_with_lock()运行结果:
81+
0.441839933395
82+
0
83+
84+
可以看出,在有全局变量的情况下,需要用锁机制防止修改过程中的冲突
85+
这样一来,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了。
86+
87+
Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核。
88+
多线程的并发在Python中就是一个美丽的梦。
89+
90+
多线程在Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核。
91+
Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。
92+
多个Python进程有各自独立的GIL锁,互不影响。
93+
94+
深入分析:
95+
一个任务在执行的过程中大部分时间都在等待IO操作,
96+
单进程单线程模型会导致别的任务无法并行执行,
97+
因此,我们才需要多进程模型或者多线程模型来支持多任务并发执行。
98+
现代操作系统对IO操作已经做了巨大的改进,最大的特点就是支持异步IO
99+
如果充分利用操作系统提供的异步IO支持,就可以用单进程单线程模型来执行多任务,
100+
这种全新的模型称为事件驱动模型,Nginx就是支持异步IO的Web服务器,
101+
它在单核CPU上采用单进程模型就可以高效地支持多任务。
102+
在多核CPU上,可以运行多个进程(数量与CPU核心数相同),充分利用多核CPU。
103+
由于系统总的进程数量十分有限,因此操作系统调度非常高效。
104+
105+
106+
处理多任务推荐的做法是: 多进程 + 协程
107+
'''

0 commit comments

Comments
 (0)