线程锁:
保证同一数据同时只修改一次,避免出错,虽然python3自带这个锁,但是你还是需要添加这个锁,因为官方并没有声明它带这个锁。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33# Author: Diedline
import threading
import time
"""
python 3版本自带这个锁(不需要),python2版本需要自己加这个锁
"""
def run(n):
lock.acquire() #获取一把锁
global num
num +=1
time.sleep(1) #因为你sleep的时候锁没释放 所以50个线程变成了串行等待50S
lock.release() #释放这把锁
lock = threading.Lock()
"""
全局变量生成一把锁
"""
num = 0
t_objs = []
for i in range(50):
t = threading.Thread(target=run,args=("t%s"%i,))
# t.setDaemon(True) #把当前线程设置为守护线程,一定要在start 之前
t.start()
t_objs.append(t)
for t in t_objs:
t.join()
"""
将t放入数组,然后每执行一次加1让t.join执行50次,实现50个线程都执行结束的效果
(不想卡住下一个进程的启动)
"""
print("all thread has finished....",threading.current_thread(),threading.active_count())
print("number:",num)
递归锁:
一把大锁中还包含一把子锁。
Locks = {
Door1:key1
Door2:key2
}
类似这样的原理实现的
生成了三把锁同时只有两把锁在进行1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44# Author: Diedline
import threading, time
def run1():
print("grab the first part data")
lock.acquire()
global num
num += 1
lock.release()
return num
def run2():
print("grab the second part data")
lock.acquire()
global num2
num2 += 1
lock.release()
return num2
def run3():
lock.acquire()
res = run1()
print('--------between run1 and run2-----')
res2 = run2()
lock.release()
print(res, res2)
num, num2 = 0, 0
lock = threading.RLock()
for i in range(1):
t = threading.Thread(target=run3)
t.start()
while threading.active_count() != 1:
print(threading.active_count())
else:
print('----all threads done---')
print(num, num2)
信号量:
互斥锁同时只允许一个线程更改数据,而信号量同时允许一定数量的线程更改数据。如下面的程序同时运行5个线程更改数据。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24# Author: Diedline
import threading, time
def run(n):
semaphore.acquire()
time.sleep(1)
print("run the thread: %s\n" % n)
semaphore.release()
if __name__ == '__main__':
semaphore = threading.BoundedSemaphore(5) # 最多允许5个线程同时运行
"""
实际效果是如果这五个线程有三个完成了就会立刻再放进三个线程
不会等5个都完成才一起放进去
"""
for i in range(22):
t = threading.Thread(target=run, args=(i,))
t.start()
while threading.active_count() != 1:
pass # print threading.active_count()
else:
print('----all threads done---')
#print(num)
Events 事件
其实就是在对全局变量不断的修改,只不过是在上面 封装了一层。
event = threading.Event() 初始化事件
event.wait() 设置等待
event.set() 设置标志位
event.clear() 清除标志位
event.is_set() 判断是否设置了标准位
标志位被设定,代表绿灯直接通行。Wait()不会阻塞。
标志位被清空,代表红灯,wait()等待变绿灯
例子使用events来模拟红绿灯1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36# Author: Diedline
import time
import threading
event = threading.Event()
def lighter():
count =0
event.set()
while True:
if count >20 and count<30: #改成红灯
event.clear() #把标准位清除
print("\033[41;1mred light is on\033[0m")
elif count>30:
event.set() #设置标志位,变绿灯
count = 0
else:
print("\033[42;1mgreen light is on\033[0m")
time.sleep(1)
count+=1
def car(name):
while True:
if event.is_set(): #代表绿灯
print("%s is running ..."%name )
time.sleep(1)
else:
print("%s is waiting..."%name)
event.wait()
print("\033[34;1m%s green light is start going\033[0m"%name)
light = threading.Thread(target=lighter,)
light.start()
car1 = threading.Thread(target=car,args=("Tesla",))
car1.start()