Sharing a Variable Between Multiple Different Threads

Sharing a variable between multiple different threads

Both T1 and T2 can refer to a class containing this variable.

You can then make this variable volatile, and this means that

Changes to that variable are immediately visible in both threads.

See this article for more info.

Volatile variables share the visibility features of synchronized but
none of the atomicity features. This means that threads will
automatically see the most up-to-date value for volatile variables.
They can be used to provide thread safety, but only in a very
restricted set of cases: those that do not impose constraints between
multiple variables or between a variable's current value and its
future values.

And note the pros/cons of using volatile vs more complex means of sharing state.

how to share variables between threads java

Integer are immutable. So changes will never be reflected between your threads.

As alternative, you could wrap the Integer in a shared object and provide thread safe methods to access/change the wrapped Integer value.

The client could would look like :

public static void main(String[] args) throws InterruptedException{
ThreadSafeInteger o = new ThreadSafeInteger();
new Te(o).start();
new In(o).start();
}

Or more simply use AtomicInteger that addresses the requirement as it wraps an int and besides it also ensures atomic update of the int value.

The client could would look like :

public static void main(String[] args) throws InterruptedException{
AtomicInteger o = new AtomicInteger();
new Te(o).start();
new In(o).start();
}

Java share a variable between two threads

If there is one and only one thread that writes to variable you can get away with making it volatile. Otherwise see the answer with AtomicInteger.


Only volatile will work in case of only one writing thread because there is only one writing thread so it always has the right value of variable.

On the sharing a variable between some threads in Python

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)

Sharing variable between threads in JAVA

You have synchronized writing of data (in inc and dec), but not reading of data (in main). BOTH should be synchronized to get predictable effects. Otherwise, chances are that main never "sees" the changes done by inc and dec.

Share variable between multiple threads

Yes, you have a slight misunderstanding of pthread_cond_wait. The man page says:

The pthread_cond_timedwait() and pthread_cond_wait() functions shall
block on a condition variable. They shall be called with mutex locked
by the calling thread or undefined behavior results.

These functions atomically release mutex and cause the calling thread
to block on the condition variable cond;

So you need to lock before calling the pthread_cond_wait. That is, your code should be:

/* If the main track is currently in use, wait for it to become available */
pthread_mutex_lock(&main_track_mutex); /* SHOULD LOCK HERE */
while(main_track_status)
pthread_cond_wait(&main_track_condition_var, &main_track_mutex);

/* Use the main track */
//pthread_mutex_lock(&main_track_mutex); /* INCORRECT */
//<..SNIP..>
pthread_mutex_unlock(&main_track_mutex);
pthread_cond_signal(&main_track_condition_var);


Related Topics



Leave a reply



Submit