Многопроцессорность в консоли IPython на компьютере с Windows - если требуется __name_

Я работаю с IPython и Spyder IDE на компьютере с Windows. Когда 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__": заявление??

2 ответа

Решение

Итак, я решил эту конкретную проблему.

  1. Поместите определение rand_string в отдельном файле, называемомtest2,
  2. Импортировать test2 как модуль в мой test.py скрипт

    import test2 as test2

  3. измените следующую строку для доступа к test2 модуль

    processes = [mp.Process(target=test2.rand_string, args=(5, output)) for x in range(4)]
    
  4. Бежать test.py

  5. Вызов myFunction()

  6. Будь счастлив:)

Решение основано на этом многопроцессорном руководстве, в котором предлагается импортировать целевую функцию из другого скрипта. Это решение обходит безопасный самовывоз if __name__-раппер, чтобы получить доступ к целевой функции.

multiprocessing не работает без работы с if __name__ == '__main__',

Вы могли бы, однако, использовать вилку multiprocessing что по существу использует dill рассматривать сеанс переводчика как файл... (короче говоря, он работает).

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 Сериализатор тоже, или вы можете построить Queue с Pool().apipeили что-то похожее на то, что вам, похоже, интересно Queue,

Получить пафос здесь: https://github.com/uqfoundation

Другие вопросы по тегам