如何按顺序启动流程?

时间:2019-06-21 13:33:48

标签: python-3.x multiprocessing

我有一个用于准备和运行流程的简单代码:

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:难道我的解决方案可以检查同一页两次或更多次?

2 个答案:

答案 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")

如您所见,这些过程是从顺序开始的,但是每个过程花费不同的时间来完成。如果您需要按顺序完成,则不能选择多处理,因为您不能保证做到这一点。