0

I have two threads running and I want them to wait for each other at a specific line using threading.Condition(). However it seems that the global variable v is not global. It is a different variable for each thread. Here is the minimum viable product:

import threading
lock = threading.Condition()
v = 0
n = 2

def barrier():
    with lock:
        global v
        v =+ 1
        print("v is increased to " + str(v))
        if v == n:
            print("v is equal to n")
            lock.notifyAll()
            print("v equals n")
            v = 0
        else:
            lock.wait()




class ServerThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        print("before barrier")
        barrier()
        print("after barrier")



for i in range(2):
            t = ServerThread()
            t.start()

The output is such as this:

before barrier
v is increased to 1
before barrier
v is increased to 1

but I want v to be increased to 2 by the second thread so the barrier can be passed. What is wrong?

juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
  • 2
    Use a mutable object like a dictionary and store the data inside. You don't even need the `global` keyword then. – Klaus D. Feb 12 '20 at 09:57
  • https://stackoverflow.com/questions/17774768/python-creating-a-shared-variable-between-threads does this answer your question? – Eternal Feb 12 '20 at 09:58
  • @KlausD. that is how I solved the problem too. –  Feb 12 '20 at 10:05
  • @Eternal Sadly, that is different from my question. My threads are created by the same class. I was just wondering if a global variable could be shared; however, it does not seem possible. –  Feb 12 '20 at 10:05
  • 1
    I have added answer making use of queue please check that @lalalal – Eternal Feb 12 '20 at 10:12
  • Don't derive from `threading.Thread` just to start a thread. Instead, pass the callable to the constructor. Less code, separation of concerns, clearer code overall. – Ulrich Eckhardt Feb 12 '20 at 11:08
  • 1
    You have a typo in your code: You wanted to write `v += 1`, you actually wrote `v =+ 1`. Just for the record: I first stripped the useless class (see comment above). Then, I added debug output before waiting on the condition and output at the beginning of `barrier()`, outputting the value of `v`. Then, I replaced the `v =+ 1` with `v = v + 1`, which fixed the thing. – Ulrich Eckhardt Feb 12 '20 at 11:17
  • @UlrichEckhardt Sorry that was my typo. – Dan D. Feb 13 '20 at 16:57
  • I don't know what typo of yours you are talking about, @DanD.. In any case this question should be closed, since it's really just a typo. – Ulrich Eckhardt Feb 14 '20 at 14:55
  • 2
    @UlrichEckhardt I wrote the code they are asking about in an answer to a question they previously asked: https://stackoverflow.com/questions/60162894/how-to-communicate-between-threads-with-wait-and-notify – Dan D. Feb 14 '20 at 14:57

1 Answers1

-1

You can make use of the queue to make share data between threads. I am not sure if this code will work according to your use case but you can do something like this:

import threading, queue
lock = threading.Condition()
q = queue.Queue()
q.put(0)
n = 2

def barrier():
    with lock:
        v_increase = q.get() + 1
        q.put(v_increase)
        print("v is increased to " + str(v_increase))
        if v_increase == n:
            print("v is equal to n")
            lock.notifyAll()
            print("v equals n")
            q.get()
            q.put(0)
        else:
            lock.wait()




class ServerThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        global v
        print("before barrier")
        barrier()
        print("after barrier")



for i in range(2):
            t = ServerThread()
            t.start()
Eternal
  • 928
  • 9
  • 22