2015-08-31 3 views
3

Я хочу назначить свои вычислительные задания более чем на один процессор, поэтому я выбираю многопроцессорность. Однако результат не тот, который я хочу.python многопроцессорность: процессы не работают

import numpy as np 
from multiprocessing import Process 

def func(begin,end): 
    print('*'*5) 
    print('begin=%d' %(begin)) 
    for i in range(begin,end): 
     for j in range(10): 
      myarray[i][j]=1 

myarray=np.zeros((12,10)) 
print(myarray) 
for i in range(4): 
    begin=i*3 
    end=(i+1)*3 
    p=Process(target=func,args=(begin,end,)) 
    p.start() 

print('*'*5) 
print(myarray) 

Я думаю, что myarray должен быть всем. Но это совсем не меняется. Зачем? Функция func не изменяет элементы myarray? я попробовал пример по этой ссылке enter link description here

from multiprocessing import Process 
def f(name): 
    print('hello',name) 

p=Process(target=f,args=('bob',)) 
p.start() 

Он ничего не показывает на экране. Зачем? Как мне закончить вычисление с помощью python? Может ли кто-нибудь дать способ полностью воспользоваться преимуществами multi-cpus?

+0

Второй сниппет печатает: '('привет', 'боб')' – alfasin

+0

@alfasin Кажется, мне это надо. Но я тестирую этот код, используя python 3.4.3 на win7 и соответствующий код (функция print to statement) с python 2.6.6 на centos6.5 в виртуальной коробке. Ничего не показывать. – dudu

+0

он работает для меня с python3.4 на Mac. – alfasin

ответ

0

Есть две проблемы: там

  1. При печати массива в конце, как вы знаете, что ваши процессы уже закончили? Вы должны вызвать join() для каждого процесса, чтобы убедиться, что они закончили.

  2. Каждый процесс имеет копию «myarray». Если вы хотите сообщить несколько процессов, вам нужно либо использовать Queue, либо Pipe. Проверить the documentation that talks about exchanging data between processes

Вот рабочий пример, используя в качестве основы один вы размещены (он не предназначен, чтобы быть быстрым, просто чтобы показать, как это делается связь):

from multiprocessing import Process, freeze_support, Queue 

def func(my_id, q, begin, end): 
    global myarray 
    print('Process %d has range: %d - %d' % (my_id, begin, end)) 
    for i in range(begin,end): 
     q.put((i, i * 2)) 

if __name__ == "__main__": 
    freeze_support() 

    q = Queue() 
    processes = [] 
    myarray=[0] * 12 
    print("At the beginning the array is ", myarray) 

    for i in range(4): 
     begin = i*3 
     end = (i+1)*3 
     p = Process(target=func, args=(i, q, begin, end)) 
     p.start() 
     processes.append(p) 

    for p in processes: 
     p.join() 

    while not q.empty(): 
     (index, value) = q.get() 
     myarray[index] = value 

    print("At the end the array is ", myarray) 

Попробуйте изменить строка p.join() от pass, чтобы посмотреть, что произойдет :)

+0

Да, соединение обязательно. Если я заменил p.join() на pass, некоторые значения будут изменены, а другие - нет. – dudu

0

Это потому, что оператор print(myarray) выполняется перед завершением процесса. Вы должны дождаться завершения процесса и выполнить этот оператор. Обратите внимание на следующее заявление: thread.join().

import numpy as np 
import threading 

lock = threading.RLock() 
thread_list = [] 
def func(begin,end): 
    print('*'*5) 
    print('begin=%d' %(begin)) 
    for i in range(begin,end): 
     for j in range(10): 
      with lock: 
       myarray[i][j]=1 

myarray=np.zeros((12,10)) 
print(myarray) 
for i in range(4): 
    begin=i*3 
    end=(i+1)*3 
    p=threading.Thread(target=func,args=(begin,end,)) 
    p.start() 
    thread_list.append(p) 

print('*'*5) 
for thread in thread_list: 
    thread.join() 
print(myarray)