0

I have 2 threads running in the same function. I want to edit the data structures later in the code, but I want to make sure that both the threads have read the data and any future changes in the dict_list and ans_list will not be read by these threads. I was thinking of making use of commands such as wait() and notify() just before mutex.acquire() but since both the threads are using the same function, the second thread will have to wait for a notify that will never come.

How can I approach this problem?

 def foo():

        //Reading the dict_list and ans_list here



        mutex.acquire()
        ans_list[room_no-1] = ""
        dict_list[room_no-1].clear()
        mutex.release()
  • 1
    This just doesn't sound like a good case for using `wait` and `notify`. Those are used for waiting for state to change and you just need to ensure only one piece of code accesses the shared state at a time. – David Schwartz Feb 11 '20 at 14:42

1 Answers1

1

I would suggest using a barrier to synchronize the threads so that both of them finish reading before any of them is allowed to write. All the threads must reach the barrier before any of them can continue.

This can be implemented via a Condition and a counter. The code looks like this:

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

def barrier():
    global v # I forgot to add this line
    with lock:
        v += 1 # This was =+
        if v == n:
            lock.notifyAll()
            v = 0
        else:
            lock.wait()

This is used like:

read
barrier()
write

This implementation is for a fixed number of threads. It is also possible to have a design that works for a dynamic number but this is not it.

Dan D.
  • 73,243
  • 15
  • 104
  • 123
  • I declared the above code globally and then I call the barrier inside my thread class. For some reason (even though I made sure to declare v globally inside barrier()) the v seems to be a different variable for each thread. What might be the reason for that? –  Feb 12 '20 at 09:43
  • 1
    I forgot to include a `global v` statement when I formed the barrier function. The Condition already protects `v`. – Dan D. Feb 12 '20 at 12:31
  • I believe when the barrier function is called by multiple threads in the same thread function, the "global v" defines v again and again. This solution works for threads that have different thread functions. However, if it's a case such as mine where each thread is going through the same function, then a globally defined data structure is the solution (such as a queue!) –  Feb 12 '20 at 16:07
  • No, that is not what global does. All it does is make the assignment assign to the global rather than create a local. It should work for multiple threads with the same thread function. You have to use more than one barrier if your threads loop so that they all finish writing before they start reading again. I will think about this and write a better example. – Dan D. Feb 12 '20 at 16:15
  • It should work for multiple threads with the same thread function. Because that is the primary use of barriers in bulk synchronous parallelism. – Dan D. Feb 12 '20 at 16:22
  • I have tested your suggestion but it did not work. Could you please look at my other post and maybe try to run the code: https://stackoverflow.com/questions/60185499/how-does-the-scope-of-the-global-variable-in-threads-work –  Feb 13 '20 at 11:40