0%

python | 线程池阻塞主线程

当我们用线程池或者多线程的时候,如果,没有阻塞主线程,可能会导致数据偏移。

关于多线程的阻塞请参考

这里重点说一下线程池。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import time
from concurrent.futures import ThreadPoolExecutor


def main(index):
time.sleep(2)
print(index)


if __name__ == '__main__':
task_list = []
pools = ThreadPoolExecutor(5)
for i in range(5):
task_list.append(pools.submit(main, i))

print("end")

这个先输出 end

所以,我们要将线程池中的线程进行堵塞,当全部完成后,我们再进行下一步。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import time
from concurrent.futures import ThreadPoolExecutor, as_completed


def main(index):
time.sleep(2)
print(index)


if __name__ == '__main__':
task_list = []
pools = ThreadPoolExecutor(5)
for i in range(5):
task_list.append(pools.submit(main, i))

# 阻塞主进程
for result in as_completed(task_list):
data = result.result()

print("end")

这个将会最终输出 end

也可以使用 wait

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import time
from concurrent.futures import ThreadPoolExecutor, wait


def main(index):
time.sleep(2)
print(index)


if __name__ == '__main__':
task_list = []
pools = ThreadPoolExecutor(5)
for i in range(5):
task_list.append(pools.submit(main, i))

wait(task_list)

print("end")

当然,我们也可以自己写。

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
import time
from concurrent.futures import ThreadPoolExecutor, as_completed


def main(index):
time.sleep(2)
print(index)


if __name__ == '__main__':
task_list = []
pools = ThreadPoolExecutor(5)
for i in range(20):
task_list.append(pools.submit(main, i))

# 阻塞主进程
while 1:
now_done = 0
task_number = len(task_list)
for task in task_list:
if task.done():
now_done += 1
if now_done == task_number:
break
time.sleep(0.001)

print("end")
请我喝杯咖啡吧~