pythonmultiprocessingmutex

How to use lock as a mutex in multiprocessing?


I want to have two processes, one writing and one reading on/from the same variable. The data written is like this:

[0, 0]
[0, 1]
[1, 0]
[1, 1]
[2, 0]
[2, 1]
[3, 0]
[3, 1]
[4, 0]
[4, 1]
[5, 0]
[5, 1]
[6, 0]
[6, 1]
[7, 0]
[7, 1]
[8, 0]
[8, 1]
[9, 0]
[9, 1]

But I'm having trouble because the reading process is reading between the variable change, forming new pairs, so I want to use a Lock/Mutex to prevent this from happening again. I guess I'd have to lock the object before changing it. OBS: The object is shared between processes using a manager.

Here is the main code:

import multiprocessing

def mde(dad, mutex):
    for i in range(10):
        for j in range(2):
            mutex.acquire()
            dad[0] = i
            dad[1] = j
            mutex.release()
def mda(dad):
    c = 0
    while c < 30:
        print(dad)
        c += 1

if __name__ == '__main__':
    manager = multiprocessing.Manager()
    mutex = manager.Lock()
    dado = manager.list([0, 0])
    p1 = multiprocessing.Process(target=mde, args=(dado, mutex,))
    p2 = multiprocessing.Process(target=mda, args=(dado,))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

As you can see I tried to lock and unlock the variable in the writing process but the result still was mixed up. What am I doing wrong?


Solution

  • Here is the corrected version (credit to MisterMiyagi). Both workers are waiting for each other to do their task, i.e. modifying the list, or displaying it.

    import multiprocessing
    
    NX = 10
    NY = 2
    
    
    def mde(dad, mutex):
        for i in range(NX):
            for j in range(NY):
                mutex.acquire()
                dad[0] = i
                dad[1] = j
                mutex.release()
    
    
    def mda(dad, mutex):
        c = 0
        while c <= NX*NY:
            mutex.acquire()
            print(dad)
            c += 1
            mutex.release()
    
    if __name__ == '__main__':
        manager = multiprocessing.Manager()
        mutex = manager.Lock()
        dado = manager.list([0, 0])
        p1 = multiprocessing.Process(target=mde, args=(dado, mutex,))
        p2 = multiprocessing.Process(target=mda, args=(dado, mutex,))
        p1.start()
        p2.start()
        p1.join()
        p2.join()