在Windows机器上的IPython控制台中进行多进程处理 - 如果需要__name__?

3
我正在使用Windows上的IPython和Spyder IDE。当IDE启动时,会加载一组py文件来定义一些函数,使我的工作更加轻松。一切都按预期进行。
现在我想将其中一个函数升级为使用多进程,在Windows上需要使用if __name__ == "__main__":语句。因此,似乎我不能直接调用该函数并从IPython控制台传递参数。
例如,其中一个py文件(我们称之为test.py)可能类似于以下代码。
import multiprocessing as mp
import random
import string

# define a example function
def rand_string(length, output):
    """ Generates a random string of numbers, lower- and uppercase chars. """
    rand_str = ''.join(random.choice(
                string.ascii_lowercase
                + string.ascii_uppercase
                + string.digits)
           for i in range(length))
    output.put(rand_str)


def myFunction():
    # Define an output queue
    output = mp.Queue()        

    # Setup a list of processes that we want to run
    processes = [mp.Process(target=rand_string, args=(5, output)) for x in range(4)]

    # Run processes
    for p in processes:
        p.start()

    # Exit the completed processes
    for p in processes:
        p.join()

    # Get process results from the output queue
    results = [output.get() for p in processes]

    print(results)

在我的IPython控制台中,我想使用以下代码行:
myFunction()

触发所有计算的操作。但在Windows上,会出现BrokenPipe错误。
当我输入

时,程序会产生一个缺陷管道错误。
if __name__ == "__main__":
     myFunction()

在py文件的末尾添加,并通过运行完整文件来实现。
runfile(test.py)

它可以工作。当然。但这使得将参数传递给函数变得非常困难,因为我总是不得不编辑test.py文件本身。

我的问题是:如何在不将其放入if __name__ == "__main__":语句中的情况下运行多进程函数??


你试过 import test 然后调用 test.myFunction() 吗? - boardrider
2个回答

4
所以,我解决了那个具体的问题。
  1. Put the defintion of rand_string in a separate file, called test2.

  2. Import test2 as module into my test.py script

    import test2 as test2

  3. modify the following line to access the test2 module

    processes = [mp.Process(target=test2.rand_string, args=(5, output)) for x in range(4)]
    
  4. Run test.py

  5. Call myFunction()

  6. Be Happy :)

该解决方案基于这个多进程教程,该教程建议从另一个脚本中导入目标函数。通过if __name__包装器绕过安全的自我导入,以访问目标函数。

3

multiprocessing如果没有使用if __name__ == '__main__'运行,将无法正常工作。

不过,你可以使用一个基于dillmultiprocessing分支来处理解释器会话,就像处理文件一样……(简而言之,它可以正常工作)。

Python 2.7.9 (default, Dec 11 2014, 01:21:43) 
Type "copyright", "credits" or "license" for more information.

IPython 3.0.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: from pathos.multiprocessing import ProcessingPool as Pool

In [2]: def squared(x):
   ...:     return x**2
   ...: 

In [3]: x = range(10)

In [4]: p = Pool()

In [5]: p.map(squared, x)
Out[5]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

In [6]: res = p.imap(squared, x)

In [7]: list(res)
Out[7]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

In [8]: 

你可以使用内置的multiprocessing,并通过dill序列化程序进行增强,或者使用Pool().apipe构建一个Queue,这两种方法更符合您对Queue感兴趣的需求。
获取pathos:https://github.com/uqfoundation

看起来值得一试,但我正在使用Python 3.4,而pathos目前不支持它。也许在两个月后,下一个版本将会发布,该版本也支持Windows操作系统。 - RaJa
pathos的主干/主线现在支持Windows,但仍然只支持2.x。不过很快就会支持3.xpathos.multiprocessing的核心现在已经独立成一个叫做multiprocess的包,它可以在2.x3.x上工作,并且也支持Windows。 - Mike McKerns

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接