'if __name__ ==“__ main__”后面的任何内容:'不执行

时间:2012-02-05 22:26:39

标签: python multiprocessing

所以,这是我的情况。

我在Eclipse中使用PyDev,在Windows中使用Python解释器版本2.7.2。

我正在使用内置的多处理库试图分离出一堆进程来并行化一个计算密集型的循环。我看过的教程说要使用,

if __name__ == "__main__":

以防止它产生近乎无限的过程并使我的系统瘫痪,基本上。

问题是,我是从一个模块调用它,而不是我的主脚本;因此,在它被执行之后什么都没有。完全没有并行机会。当然,如果我删除它,我会收到infiniprocess垃圾邮件,它会杀死执行代码的机器。

为了参考,这里是相关的代码:

from tribe import DataCache
from tribe import WorldThread
from tribe import Actor
from time import sleep
import multiprocessing

class World:
def __init__(self,numThreads,numActors,tickRate):
    print "Initalizing world..."
    self.cache = DataCache.DataCache()
    self.numThreads = numThreads
    self.numActors = numActors
    self.tickRate = tickRate
    self.actors = []
    self.processes = []
    for i in range(numActors):
        self.actors.append(Actor.Actor("test.xml",self.cache))
    print "Actors loaded."
def start_world(self):
    print "Starting world"
    run_world = True;
    while run_world:
        self.world_tick()
        sleep(2)

def world_tick(self):
        if __name__ == '__main__':
            print "World tick"
            actor_chunk = len(self.actors)/self.numThreads
            if len(self.processes)==0:
                for _ in range(self.numThreads):
                    new_process = multiprocessing.Process(WorldThread.WorldProcess.work, args=(_, self.actors[_*actor_chunk,(_+1)*actor_chunk]))

它正在呼唤的课程:

class WorldProcess():
def __init__(self):
    print "World process initilized."
    ''' Really, I'm not sure what kind of setup we'll be doing here yet. '''
def work(self, process_number, actors):
    print "World process" + str(process_number) + " running."
    for actor in actors:
        actor.tick()
    print "World process" + str(process_number) + " completed."

我在评估中是否正确,如果名称 ==“main”:只有在可执行脚本中有检查才能检查?如果是这样,你如何安全地从模块中分离出进程?如果没有,为什么不在这里工作?

2 个答案:

答案 0 :(得分:2)

要控制流程数量,请使用Pool中的multiprocessing类:

from multiprocessing import Pool
p = Pool(5)
def f(x):
     return x*x
p.map(f, [1,2,3])

(编辑:根据评论,这只是Pool类的 howto see更多)

不需要使用__name__,因为您明确地将{{1>} 实际的python函数传递给了运行。

此:

Process

非常糟糕。简化它。

更好的模式将是:

def world_tick(self):
    if __name__ == '__main__':
        print "World tick"
        actor_chunk = len(self.actors)/self.numThreads
        if len(self.processes)==0:
            for _ in range(self.numThreads):
                new_process = multiprocessing.Process(WorldThread.WorldProcess.work, args=(_, self.actors[_*actor_chunk,(_+1)*actor_chunk]))

希望这有帮助!

作为旁注,挑选您的参数并将其传递给其他流程将导致导入您的模块。所以,最好确保你的模块没有预先形成任何分叉/魔术/工作,除非它被告知(例如,只有函数/类定义或class WorkArgs(object): ... many attributes follow ... def proc_work(world_thread, work_args): world_thread.WorldProcess.work(work_args.a, work_args.b, ... etc) p = Pool(5) p.map(proc_work, [(world_thread, args0), (world_thread, args1), ...]) 魔法,而不是实际的代码块)。

答案 1 :(得分:2)

添加此作为答案,因为它在评论中:

if __name__ == "__main__"是您在脚本的根级别所做的事情,它将成为一个入口点。它是一种只在直接执行脚本时才能执行操作的方法。

如果您有一个作为入口点的脚本,那么您可以使用名称== main。在您想要进行多处理的模块中,您只需循环并启动流程,就像循环和启动线程一样。