代码已大大简化,但应该用来说明我的问题。
S = ('A1RT', 'BDF7', 'CP09')
for s in S:
if is_valid(s): # very slow!
process(s)
我有一个从网站刮取的字符串集合。 (字符串将定期从站点搜索中检索。)这些字符串中的每一个都需要通过网络与第三方进行验证。验证过程有时可能很慢,这是有问题的。由于上述代码的迭代性质,可能需要一些时间才能验证和处理最后一个字符串。
是否有正确的方法在Python中并行化上述逻辑?坦率地说,我对并发/并行处理概念并不是很熟悉,但似乎它们在这种情况下可能会有用。想法?
答案 0 :(得分:1)
concurrent.futures
模块是开始处理“令人尴尬的并行”问题的好方法,并且可以在单个进程中使用多个进程或多个线程轻松切换。
在您的情况下,听起来在网络上的其他计算机上正在进行“艰苦工作”,您的主程序将花费大部分时间等待它们提供结果。如果是这样,线程应该正常工作。这是一个完整的,可执行的玩具示例:
import concurrent.futures as cf
def is_valid(s):
import random
import time
time.sleep(random.random() * 10)
return random.choice([False, True])
NUM_WORKERS = 10 # number of threads you want to run
strings = list("abcdefghijklmnopqrstuvwxyz")
with cf.ThreadPoolExecutor(max_workers=NUM_WORKERS) as executor:
# map a future object to the string passed to is_valid
futures = {executor.submit(is_valid, s): s for s in strings}
# `as_complete()` returns results in the order threads
# complete work, _not_ necessarily in the order the work
# was passed out
for future in cf.as_completed(futures):
result = future.result()
print(futures[future], result)
这是一次运行的示例输出:
g False
i True
j True
b True
f True
e True
k False
h True
c True
l False
m False
a False
s False
v True
q True
p True
d True
n False
t False
z True
o True
y False
r False
w False
u True
x False
concurrent.futures
处理启动线程的所有麻烦,为他们分配工作,并注意线程何时传递结果。
如上所述,最多10个(NUM_WORKERS
)is_valid()
次调用可以同时激活。 as_completed()
在结果准备好检索后立即返回一个未来对象,executor
自动将计算结果的线程另一个字符串is_valid()
用于咀嚼。