python标准库中从多处理到分布式处理

python标准库中从多处理到分布式处理,python,multithreading,multiprocessing,distributed,parallel-python,Python,Multithreading,Multiprocessing,Distributed,Parallel Python,我正在gitHub上学习分布式处理。我要感谢eliben为我做的这件好事。我读过他的解释,但有一些不好的地方。据我所知,该代码用于在多台机器/客户端中分发任务。我的问题是: 我最基本的问题是,将工作分配到不同的机器是在哪里进行的 为什么主函数中有if-else语句 让我以更一般的方式开始这个问题。我认为我们通常在一个特定块(独立内存部分)中启动一个过程,而不是像这样一次传递所有块: chunksize = int(math.ceil(len(HugeList) / float(nprocs)))

我正在gitHub上学习分布式处理。我要感谢eliben为我做的这件好事。我读过他的解释,但有一些不好的地方。据我所知,该代码用于在多台机器/客户端中分发任务。我的问题是:

  • 我最基本的问题是,将工作分配到不同的机器是在哪里进行的

  • 为什么主函数中有if-else语句

  • 让我以更一般的方式开始这个问题。我认为我们通常在一个特定块(独立内存部分)中启动一个
    过程
    ,而不是像这样一次传递所有块:

    chunksize = int(math.ceil(len(HugeList) / float(nprocs)))
    for i in range(nprocs):
    p = Process(
                target = myWorker, # This is my worker
                args=(HugeList[chunksize * i:chunksize * (i + 1)],
                HUGEQ)      
    processes.append(p)
    p.start() 
    
    在这个简单的例子中,我们有
    nproc
    进程。每个进程都会启动一个作用于指定区块的函数
    myWorker

    我的问题是:

    • 对于在每个块中工作的每个进程,我们有多少线程
  • 现在查看
    gitHub
    代码,我试图理解
    mp\u factorizer
    ?更具体地说,在这个函数中,我们没有块,而是一个巨大的队列(
    shared\u job\u q
    )。这个庞大的队列由大小最大为43的子列表组成。此队列被传递到
    factoryzer\u worker
    。在那里,我们通过
    get
    获得这些子列表,并将它们传递给串行工作程序。我知道我们需要这个队列在客户端之间共享数据

    我的问题是:

    • 我们是否为每个
      nproc
      (=8)进程调用
      factorizer\u worker
      函数的实例
    • 每个流程工作的数据的哪一部分?(通常,我们有8个进程和43个块。)
    • 每个进程有多少个线程
    • 是否从每个进程线程调用
      函数

  • 谢谢你抽出时间

    只有在多台计算机上实际运行脚本时,才会将脚本分发到多台计算机。第一次运行脚本(不带--client选项)时,它会在特定IP/端口上启动Manager服务器,该端口承载共享作业/结果队列。除了启动Manager服务器外,runserver还将通过调用mp_factorizer充当工作进程。它还负责从结果队列收集结果并进行处理。您可以自行运行此脚本并获得完整的结果

    但是,您也可以通过使用--client选项在其他机器上运行脚本,将分解工作分发到其他机器。这将调用runclient,它将连接到您在脚本初始运行时启动的现有Manager服务器。这意味着客户端正在访问runserver使用的相同共享队列,因此它们都可以从相同的队列中提取工作并将结果放入相同的队列

    上述内容应涵盖问题1和2

    我不太清楚你在第三个问题中问了什么。我想您可能想知道为什么我们不显式地将列表中的一个块传递给每个工作人员(如您所包含的示例中),而不是将所有的块放入队列中。答案是因为
    runserver
    方法不知道实际将有多少工人。它知道它将启动8个工人。但是,它不希望将
    HugeList
    拆分为八个块,并将它们发送到它正在创建的8个进程,因为它希望支持远程客户端连接到
    管理器并执行工作。因此,它为每个块选择一个任意大小(
    43
    ),并将列表划分为消耗整个
    HugeList
    所需大小的块,并将其粘贴在
    队列中。以下是
    runserver
    中的代码:

    chunksize = 43
    for i in range(0, len(nums), chunksize):
        #print 'putting chunk %s:%s in job Q' % (i, i + chunksize)
        shared_job_q.put(nums[i:i + chunksize]) # Adds a 43-item chunk to the shared queue.
    
    这样,您就可以连接到
    管理器
    服务器,从
    共享作业
    中获取一个块,处理它,然后返回结果

    我们是否为每个NPROC(=8)进程调用factorzer_worker函数的实例

    每个流程工作的数据的哪一部分?(通常,我们有8个进程和43个块。)

    我们没有43块。我们有X个块,每个块大小为43。每个工作进程只是从队列中抓取块并进行处理。它得到哪一部分是任意的,取决于有多少工人以及每个工人的速度

    每个进程有多少个线程

    一个。如果您的意思是,现在脚本的每个实例都有许多工作进程,那么服务器进程中有8个,客户端进程中有4个

    是否从每个进程线程调用get函数


    我不知道你的意思。

    谢谢你的回答,我正在研究。给我一些时间来处理你的逻辑。:)因此,在
    mp\u factorizer
    中,我们开始
    nprocs
    过程。每个进程都掌握
    共享作业队列,并在
    factorizer\u worker
    中开始处理该队列。从现在起,我了解到一个进程对应于一个在不同内存部分(块)上工作的线程。因此,每个线程获得(
    get_nowait
    )一个子列表,并对作业中的n执行行
    outdict={n:factorize_naive(n)}
    。服务器上的8个线程(进程)几乎同时发生这种情况。所有线程进程都通过
    get\u nowait()
    同步。你能纠正一下我的逻辑吗?谢谢@Thoth是的,假设您将“线程”一词替换为“进程”,那么这一切都是正确的。这里没有任何多线程,都是多处理的。很好!所以最后一个问题
    是否从每个进程线程调用函数?
    现在对您或我来说都更清楚了。:)。get函数(
    get