当我们用线程池或者多线程的时候,如果,没有阻塞主线程,可能会导致数据偏移。
关于多线程的阻塞请参考
这里重点说一下线程池。
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")
|