Reputation: 849
I want to assign my computing jobs to more than one cpu, so I choose multiprocessing. However, the result is not what I want.
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)
I think that myarray should be all ones. But it doesn't change at all. Why? The func function does not change elements of myarray? I tried the example from this linkenter link description here
from multiprocessing import Process
def f(name):
print('hello',name)
p=Process(target=f,args=('bob',))
p.start()
It shows nothing on the screen. Why? How should I finish my computation with python? Can anyone give a way of fully take advantage of multi-cpus?
Upvotes: 3
Views: 1726
Reputation: 1
That is because the print(myarray)
statement execute before the process end. You should wait for the process end and then execute this statement. Please note the thread.join()
statement at the following.
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)
Upvotes: 0
Reputation: 23016
There are two problems there:
When you print your array at the end, how do you know your processes have already finished? You need to invoke join()
on each process to ensure they have finished.
Each process has a copy of "myarray". If you want to communicate several processes you need to either use a Queue
or a Pipe
. Check the documentation that talks about exchanging data between processes
Here is a working example using as base the one you posted (it is not intended to be fast, just to show how the communication is done):
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)
Try to change the line p.join()
by pass
to see what happens :)
Upvotes: 2