Because threads
use the same memory so you could use global variable like in normal program
import random
from threading import Thread
epochs = 2
success = [0] * epochs
def do():
global temp
if random.random() > 0.5:
print(' add')
temp += 1
print("Teh current temp is {0}".format(temp))
for epoch in range(epochs):
print("iteration: {0}".format(epoch))
temp = 0
t1 = Thread(target=do)
t2 = Thread(target=do)
t1.start()
t2.start()
t1.join()
t2.join()
success[epoch] = temp
You could eventually use Lock()
to block other threads when you access shared variable. And eventually you can send lock
as argument. But because Python can't run two threads at the same time so I don't know if it is really needed.
import random
from threading import Thread
from threading import Lock
epochs = 2
success = [0] * epochs
def do(lock):
global temp
if random.random() > 0.5:
print(' add')
lock.acquire() # block other threads
temp += 1
lock.release() # unblock other threads
print("Teh current temp is {0}".format(temp))
lock = Lock()
for epoch in range(epochs):
print("iteration: {0}".format(epoch))
temp = 0
t1 = Thread(target=do, args=(lock,))
t2 = Thread(target=do, args=(lock,))
t1.start()
t2.start()
t1.join()
t2.join()
success[epoch] = temp
If you would have to only add some value without displaing then I would rather use queue
to send 0
or 1
to main thread and add it to temp
in main thread.
import random
from threading import Thread
from queue import Queue
epochs = 2
success = [0] * epochs
def do(q):
if random.random() > 0.5:
q.put(1)
else:
q.put(0)
q = Queue()
for epoch in range(epochs):
print("iteration: {0}".format(epoch))
temp = 0
t1 = Thread(target=do, args=(q,))
t2 = Thread(target=do, args=(q,))
t1.start()
t2.start()
temp += q.get()
temp += q.get()
t1.join()
t2.join()
success[epoch] = temp
print(temp)
And this method should works also with multiprocessking
, ray
, joblib
, etc.
EDIT:
Last version with ray
. I use bigger epochs and more processes in epoch
import random
import ray
ray.init()
@ray.remote
def do():
if random.random() > 0.5:
print('do: 1')
return 1
else:
print('do: 0')
return 0
epochs = 5
success = [0] * epochs
for epoch in range(epochs):
print("iteration: {0}".format(epoch))
results = ray.get([do.remote() for _ in range(5)])
temp = sum(results)
success[epoch] = temp
print('Temp:', temp)
Last version with joblib
import random
from joblib import Parallel, delayed
def do():
if random.random() > 0.5:
print('do: 1')
return 1
else:
print('do: 0')
return 0
epochs = 5
success = [0] * epochs
pool = Parallel(n_jobs=3)
for epoch in range(epochs):
print("iteration: {0}".format(epoch))
#results = Parallel(n_jobs=3)(delayed(do)() for _ in range(5))
results = pool(delayed(do)() for _ in range(5))
temp = sum(results)
success[epoch] = temp
print('Temp:', temp)