我有一个用于准备和运行流程的简单代码:
with Pool(processes=4) as pool:
pool.map(check_url, range(0, 240000)
这是验证站点上页面是否存在的必要条件,例如site.com/298-存在,site.com / 17-不存在。因此,我需要检查240,000页。 问题是,当您运行脚本时,range()给出的值不按顺序排列,即我在输出中看到:
Page found: 26545
Page not found: 1523
Page found: 45
Page found: 9
Page found: 4568
Page not found: 256
....
我尝试使用准备好的列表而不是范围:
urls = [i for i in range(0, 240000)]
当我将其打印出来时,我看到了一个按顺序排列的数字列表,但是过程仍然继续以乱序开始。 如何使流程按顺序运行?
UPD:难道我的解决方案可以检查同一页两次或更多次?
答案 0 :(得分:1)
在Python documentation on Pool中,您可以看到“地图”的签名:
[1, 'a', 3, 'b', 5, 'c', 7]
您的作业是并行提交的,这意味着它们不能保证按顺序执行。如果您需要按顺序轮询站点,则并行化可能不是最佳选择,您可以考虑使用for循环来保证顺序行为。
答案 1 :(得分:1)
Pool.map的重点是将任务分开,然后让它们分别完成(https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool.Pool.map)。如果您要按顺序提供数据,则需要按顺序发送数据,即:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<scope>provided</scope>
</dependency>
给出输出:
import multiprocessing as mp
from time import sleep
import random
def f(x):
worker_name = mp.current_process().name
print(f"[{x}] by {worker_name}")#start
timetosleep=random.randrange(10)/10
sleep(timetosleep)
print(f"-[{x}] by {worker_name}")#done
return x
if __name__ == '__main__':
print("Init")
with mp.Pool(processes=16) as p:
for i in range(10):
p.apply_async(f, (i,))
p.close()
p.join()
print("Done")
如您所见,这些过程是从顺序开始的,但是每个过程花费不同的时间来完成。如果您需要按顺序完成,则不能选择多处理,因为您不能保证做到这一点。