前言

Python3.6.6/threading/threading.Event,如何给每个线程加一个控制开关。

需求分析

在爬虫项目中,threading模块的使用率还是很高的,
每个线程之间独立,如果一个线程成功完成了任务退出了,
其他的线程还要继续跑吗? 会造成资源浪费,如何给线程之间弄个信号源,
一个线程完成任务,其他线程及退出呢?当然可能有很多方法完成目的,
我只把自己使用过的方法做个记录。

实践

test.py

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
45
46
import random
import threading


class Calculation(threading.Thread):

def __init__(self, signal):
threading.Thread.__init__(self)
# 开关控制
self.singal = signal

def run(self):
self.test()
return

def test(self):
while True:
num = random.randint(0, 100)
print(threading.currentThread(), num)
# 如果其他线程完成任务打开开关,当前线程就退出
if self.singal.isSet():
print(threading.currentThread(), '其他线程已经完成任务,退出!')
break

# 如果随机数符合了条件,就把开关打开
if num == 66:
print(threading.currentThread(), '当前线程完成任务,退出!')
self.singal.set()
break
return


if __name__ == '__main__':
# 初始“开关” ,默认值 False
event_obj = threading.Event()
# 线程列表
threads_list = []
# 开始线程 5个线程
for thread in range(0, 5):
threads_list.append(Calculation(signal=event_obj))

for t in threads_list:
t.start()

# for t in threads:
# t.join()

看看输出结果,也没什么其他好说的

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
# 数据太长,删过一部分,重要的流程还在
# \Pythonvenv\py3\Scripts\python.exe test.py
<Calculation(Thread-1, started 24500)> 1
<Calculation(Thread-1, started 24500)> 34
<Calculation(Thread-1, started 24500)> 60
<Calculation(Thread-1, started 24500)> 13
<Calculation(Thread-2, started 24400)> 36
<Calculation(Thread-2, started 24400)> 60
<Calculation(Thread-1, started 24500)> 80
<Calculation(Thread-3, started 13304)> 19
<Calculation(Thread-2, started 24400)> 87
<Calculation(Thread-1, started 24500)> 97
<Calculation(Thread-3, started 13304)> 36
<Calculation(Thread-2, started 24400)> 3
<Calculation(Thread-1, started 24500)> 2
<Calculation(Thread-4, started 18092)> 38
<Calculation(Thread-5, started 16736)> 62
<Calculation(Thread-3, started 13304)> 33
<Calculation(Thread-2, started 24400)> 20
<Calculation(Thread-2, started 24400)> 97
<Calculation(Thread-2, started 24400)> 58
<Calculation(Thread-2, started 24400)> 23
<Calculation(Thread-5, started 16736)> 37
<Calculation(Thread-3, started 13304)> 91
<Calculation(Thread-1, started 24500)> 13
<Calculation(Thread-4, started 18092)> 11
<Calculation(Thread-2, started 24400)> 16
<Calculation(Thread-2, started 24400)> 66
<Calculation(Thread-2, started 24400)> 当前线程完成任务,退出!
<Calculation(Thread-3, started 13304)> 64
<Calculation(Thread-1, started 24500)> 19
<Calculation(Thread-4, started 18092)> 92
<Calculation(Thread-5, started 16736)> 24
<Calculation(Thread-3, started 13304)> 其他线程已经完成任务,退出!
<Calculation(Thread-1, started 24500)> 其他线程已经完成任务,退出!
<Calculation(Thread-4, started 18092)> 其他线程已经完成任务,退出!
<Calculation(Thread-5, started 16736)> 其他线程已经完成任务,退出!

Process finished with exit code 0

知识点

1
2
3
4
5
6
7
8
9
10
11
12
13
# 定义一个开关
obj = threading.Event()

# 把开关传进每个线程

# 查看开关的状态,返回True或False,默认值 False
obj.isSet()

# 打开开关,此时值为True
obj.set()

# 关闭开关,此时值为False
obj.clear()

End.