我正在研究gitHub
关于分布式处理的code。我要感谢eliben
这个不错的post。我已经阅读了他的解释,但有一些黑点。据我了解,该代码用于在多台机器/客户端中分发任务。我的问题是:
我最基本的问题是工作在不同机器上的分配情况?
为什么main函数中有if else语句?
让我以更一般的方式开始这个问题。我认为我们通常在特定的块(独立内存部分)中启动Process
而不是像这样一次传递所有块:
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()
在这个简单的情况下,我们有nprocs
个进程。每个进程都会启动在指定块上工作的函数myWorker
的实例。
我的问题是:
现在查看gitHub
代码我想了解mp_factorizer
?更具体地说,在这个函数中,我们没有块,而是一个庞大的队列(shared_job_q
)。这个庞大的队列由最大为43的子列表组成。此队列将传递到factorizer_worker
。通过get
我们获取这些子列表并将它们传递给序列工作者。我知道我们需要这个队列来在客户端之间共享数据。
我的问题是:
factorizer_worker
(= 8)进程调用nprocs
函数的实例?get
函数吗?感谢您的时间。
答案 0 :(得分:2)
只有在多台计算机上实际运行脚本时才会分发到多台计算机。第一次运行脚本(没有--client选项)时,它会在特定IP /端口上启动Manager服务器,该端口承载共享作业/结果队列。除了启动Manager服务器之外,runserver还将通过调用mp_factorizer充当worker。它还负责从结果队列中收集结果并对其进行处理。您可以单独运行此脚本并获得完整的结果。
但是,您也可以通过使用--client选项在其他计算机上运行脚本,将分解工作分发到其他计算机。这将调用runclient,它将连接到您在初始运行脚本时启动的现有Manager服务器。这意味着客户端正在访问runserver正在使用的相同共享队列,因此他们都可以从中拉出工作并将结果放到相同的队列中。
以上内容应涵盖问题1和问题2。
我不确定你在问题3中提出的问题。我想你想知道为什么我们没有明确地将一大块列表传递给每个工作者(比如你包括的例子),而不是将所有的块放入队列中。答案是因为runserver
方法不知道实际上会有多少工人。它知道它将启动8名工人。但是,它不希望将HugeList
拆分为八个块并将它们发送到它正在创建的8个进程,因为它希望支持远程客户端与Manager
的连接以及正在进行的工作。因此,它为每个块(43
)选择一个任意大小,并将列表分成尽可能多的块,以消耗整个HugeList
,并将其粘贴到{{1} }}。这是Queue
中执行此操作的代码:
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.
服务器,从Manager
抓取一个块,处理它,然后返回结果。
我们是否为每个nprocs(= 8)进程调用factorizer_worker函数的实例?
是
每个流程的哪部分数据有效? (通常,我们有8个进程和43个块。)
我们没有43块。我们有X个块,每个块大小为43个。每个工作进程只是从队列中抓取块并处理它们。它获得的部分是任意的,取决于有多少工人以及每个人的工作速度。
每个进程有多少个线程?
一。如果您的意思是现在每个脚本实例都存在许多工作进程,则服务器进程中有8个,每个客户端进程中有4个。
是否从每个进程线程调用函数?
不确定你的意思。