как использовать многопроцессорный модуль python

Я использую двухъядерный процессор Intel Pentium(R) E5700 с частотой 3,00 ГГц и оперативной памятью 2 ГБ. Я пытаюсь изучить модуль Python multiprocessing. Я написал простую программу, которая выполняет сложение, но она не работает; Я получаю только число ядер 2. Что-то не так с моим компьютером или моим кодом?

import multiprocessing
print "number of core ",multiprocessing.cpu_count()



def calc(a,b):
    c= a+b
    return c

if __name__ =='__main__':

    p1 = multiprocessing.Process(target=calc,args=(3,5) )
    p1.start()
    p2 = multiprocessing.Process(target=calc,args=(2,2) )
    p2.start()



p1.join()
p2.join()

person guiboy    schedule 15.02.2015    source источник
comment
изменить return c на print c   -  person itzMEonTV    schedule 15.02.2015
comment
почему изменен возврат к печати, это функция, она работает отлично, когда я называю ее calc (2,3), я получаю 5   -  person guiboy    schedule 15.02.2015
comment
Если у вас двухъядерный компьютер, то количество процессоров равно двум. Что заставляет вас думать, что это неправильно? Что вы ожидаете, что это будет?   -  person Steven Kryskalla    schedule 15.02.2015
comment
k..тогда как вы узнаете, что функция выполняется вашей программой? Также Вы получаете number of core 2. Тогда в чем проблема в вашей программе?   -  person itzMEonTV    schedule 15.02.2015
comment
Из вашего вопроса не ясно, какая часть программы не работает. Какое поведение вы видите? Какое поведение вы ожидаете увидеть?   -  person dano    schedule 15.02.2015
comment
@ Lost-theory Я ожидаю результата, ты не думаешь, что я должен получить 8 и 4 в результате, но я получаю только количество ядер   -  person guiboy    schedule 15.02.2015
comment
Он пытается выяснить, почему функция не выводит. Единственный результат, который он получает, — это количество ядер, которые у него есть. Это правильно?   -  person Zizouz212    schedule 15.02.2015
comment
если вы хотите, чтобы результат не только печатался в терминале, обратитесь к заголовку stackoverflow.com/questions/10797998/   -  person itzMEonTV    schedule 15.02.2015
comment
@guiboy Нет, вы не увидите, что 8 и 4 будут напечатаны, если вы явно не print их. Единственное, что вы печатаете, это "number of core ", multiprocessing.cpu_count(), так что это все, что будет напечатано.   -  person dano    schedule 16.02.2015
comment
Если я правильно помню, return сделает так, чтобы система могла его использовать, но не выводит на экран. Вы можете использовать print и return в одной и той же функции, если print стоит перед return -> Хорошо, если вам нужно увидеть вывод и одновременно сделать его пригодным для использования системой.   -  person Zizouz212    schedule 16.02.2015


Ответы (3)


Я предлагаю вам использовать Queue. Посмотрите этот пример:

from multiprocessing import Queue, Process

def calc(a, b, queue):
    queue.put(a + b)

if __name__ == '__main__':
    queue = Queue()
    p1 = Process(target = calc, args = (4, 4, queue,))
    p2 = Process(target = calc, args = (4, 4, queue,))
    p1.start()
    p2.start()
    result_1 = queue.get()
    result_2 = queue.get()
    print(result_1, result_2)
    p1.join()
    p2.join()
    input()

>>> 8 8

Тот же код динамически:

from multiprocessing import Queue, Process, cpu_count

def calc(a, b, queue):
    queue.put(a + b)

if __name__ == '__main__':
    queue = Queue()
    processes = []
    for i in range(cpu_count()):
        processes.append(Process(target = calc, args = (4, 4, queue,)))
        processes[-1].start()
    results = []
    for i in range(cpu_count()):
        results.append(queue.get())
    print(results)
    for process in processes:
        process.join()

>>> [8, 8] # if you have two cores
person João Paulo    schedule 15.02.2015
comment
оба примера иногда работают, иногда застревают, как цикл while, я думаю, что многопроцессорность не работает должным образом в Windows - person guiboy; 16.02.2015
comment
это работает ... проверьте, не используете ли вы IDLE для запуска кода, и в дополнительных параметрах загрузки в msconfig конфигурация позволяет вам использовать все ядра. - person João Paulo; 16.02.2015

все работает отлично, включая мою программу calc под pycharm, единственная проблема была в IDE, я использовал pyscripter

person guiboy    schedule 15.02.2015

В вашей функции calc вам нужно изменить return на print. На моей четырехъядерной машине (под управлением OS X Mavericks) это мой вывод при запуске скрипта в терминале. Вы также должны указать p1.join() и p2.join() как часть вашего if __name__ == "__main__.

Last login: Sun Feb 15 15:47:18 on ttys001
imac:~ zinedine$ cd '/Users/zinedine/Documents/' && '/usr/local/bin/pythonw'
'/Users/zinedine/Documents/example.py'  && echo Exit status: $? && exit 1
number of cores  4
8
4
Exit status: 0
logout

[Process completed]

Код, который я использовал в Терминале...

import multiprocessing

print "number of cores ", multiprocessing.cpu_count()

def calc(a, b):
    c = a + b
    return c

if __name__ == "__main__":
    p1 = multiprocessing.Process(target = calc, args = (3, 5) )
    p1.start()

    p2 = multiprocessing.Process(target = calc, args = (2, 2) )
    p2.start()

    p1.join()
    p2.join()

После использования Python Launcher.app он открывается в терминале и выдает результат, который я дал выше...

person Zizouz212    schedule 15.02.2015
comment
я все еще не работал. b>': p1 = multiprocessing.Process(target=calc,args=(3,5)) p1.start() p2 = multiprocessing.Process(target=calc,args=(2,2)) p2.start() p1.присоединиться() p2.присоединиться() - person guiboy; 15.02.2015
comment
Почему вы делаете from multiprocessing import Process и import multiprocessing? Просто сделайте простое import multiprocessing. Но это не главное. Как вы думаете, вы можете внести изменения в свой вопрос, описывающий ваш результат? - person Zizouz212; 15.02.2015
comment
этот скрипт может работать только как файл python. Поскольку обработка выполняется в if __name__ =='__main__':. Поэтому нет необходимости в отступах для p1.join() и p2.join. Он все равно будет выполняться - person itzMEonTV; 16.02.2015
comment
нет, я не делаю многопроцессорный импорт, я делаю многопроцессорный импорт, вы можете проверить мой код в своем терминале, извините, я немного запутался - person guiboy; 16.02.2015
comment
@latheefitzmeontv На самом деле это ошибка, когда нет отступа. В Windows этот код будет выполняться в каждом дочернем процессе, а код в блоке if __name__ ... — нет. Очевидно, что это нежелательно, так как это приведет к сбою обоих дочерних процессов. У вас была бы та же проблема, если бы вы импортировали модуль, а не выполняли его напрямую. - person dano; 16.02.2015
comment
@dano это правильно. Если это импорт, должна быть проблема. Так как он запрограммировал многопроцессорность под if main. K тут не при чем ;) - person itzMEonTV; 16.02.2015
comment
@latheefitzmeontv Если бы вы попытались запустить этот код в Windows, это было бы проблемой. Windows необходимо повторно импортировать модуль __main__ в каждый дочерний процесс, созданный модулем multiprocessing, чтобы выполнить calc. Этот импорт завершится ошибкой из-за проблемы с отступом, поэтому ни один из дочерних процессов не будет выполняться должным образом. Все будет хорошо работать в Linux/OSX, потому что они поддерживают fork и не требуют повторного импорта __main__ в каждом потомке. - person dano; 16.02.2015
comment
@Zizouz212 Zizouz212 Ваш код всегда будет работать, потому что вы сделали правильный отступ. Код OP не будет работать в Windows, потому что вызовы join() не имеют правильного отступа. - person dano; 16.02.2015
comment
Итак, если OP делает отступ join(), код будет работать в Windows? - person Zizouz212; 16.02.2015
comment
этот код иногда работает правильно, иногда его застревание, как в цикле while; из многопроцессорного импорта Queue, Process, cpu_count def calc(a, b, queue): queue.put(a + b) if name == 'main': queue = Queue()processes = [] for i in range(cpu_count()):processes.append(Process(target = calc, args = (4, 4, queue ,))) процессы[-1].start() results = [] for i in range(cpu_count()): results.append(queue.get()) print(results) для процесса в процессах: process.join( ) - person guiboy; 16.02.2015
comment
иногда? О, убедитесь, что вы прокомментировали правильный вопрос! :) - person Zizouz212; 16.02.2015