python - Python - 使用多线程对列表中的元素执行操作
问题描述
我想通过在 Python 中使用多线程对同一列表中的元素做一些事情。例如,同时下载一个列表中的 3 个文件。
这是我的代码:
import threading
import time
thread_count = 3
l = [x for x in range(0, 10)]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
def do_sth(x):
print('%s\n' % x)
time.sleep(1)
def worker():
for x in l:
l.remove(x)
do_sth(x)
threads = []
for x in range(0, thread_count):
t = threading.Thread(target=worker)
threads.append(t)
for t in threads:
t.start()
print('Started: %s' % t)
但是在输出中总是有一些东西消失了:
Started: <Thread(Thread-6, started 5924)>
0
1
Started: <Thread(Thread-7, started 2860)>
2
Started: <Thread(Thread-8, started 15648)>
4
5
6
8
9
解决方案
列表不是线程安全的(这意味着如果您有多个线程/进程使用单个列表,则会出现并发问题)。请改用队列。这是适用于您的用例的文档中的示例:
import threading
import time
import queue
q = queue.Queue()
def worker():
while True:
x = q.get()
if x is None:
break
do_sth(x)
q.task_done()
def do_sth(x):
print(x)
time.sleep(1)
threads = []
thread_count = 3
for x in range(0, thread_count):
t = threading.Thread(target=worker)
threads.append(t)
t.start()
print('Started: %s' % t)
for x in range(0, 10):
q.put(x)
# block until all tasks are done
q.join()
# stop workers
for _ in threads:
q.put(None)
for t in threads:
t.join()
推荐阅读
- firebase - 路由器在第一次尝试时不重定向
- ios - 点击手势在文本字段上的 iOS 13.4 上不起作用
- java - 使用 VAVR 惯用地处理异常
- c# - C# AdaptiveCards 1.2.4 简单卡片反序列化的问题
- datatables - 如何在数据表单元格上显示工具提示以及如何在工具提示中以表格格式填充数据?
- scala - 一轮只处理几个文件
- excel - 无法从不同的工作表执行用户表单
- php - PHP file_get_contents() 在 PLESK / CENTOS7 服务器上不起作用
- vue.js - 嘿!你知道如何在 Nuxt 中动态更改布局而不使用 store 吗?
- javascript - 如何使用 jquery 从 HTML 中排除 thead、tfoot 和 input[type=checkbox]?