educative.io

Educative

Quiz question 3: Can you solve the ping-pong problem using a condition variable?

Quiz question 3: Can you solve the ping-pong problem using a condition variable?

The provided code solution for this question did not work for me; it just hanged in an infinite loop. I had to modify to get it to work. My solution is below, let me know any comments:

from multiprocessing import Condition, Process, Value
from ctypes import c_bool
import time


def process_A(cv, flag, exit):
    while not exit.value:
        with cv:
            while flag.value is False:
                cv.wait()
                # it is possible the other process could exit whilst waiting
                if exit.value:
                    return
            
            # need to have flush=True to actually display ping-pong in order
            print("ping", flush=True)
            flag.value = False
            
            # don't forget to notify
            cv.notify()
        
        # the other process is likely to exit during this sleep period
        time.sleep(0.05)
    
    # it is possible the other process could be waiting
    # after exiting the loop so need to notify
    with cv:
        cv.notify()


def process_B(cv, flag, exit):
    # this is just the mirror image of the other process
    while not exit.value:
        with cv:
            while flag.value is True:
                cv.wait()
                if exit.value:
                    return
            print("pong", flush=True)
            flag.value = True
            cv.notify()
    with cv:
        cv.notify()


if __name__ == '__main__':
    cv = Condition()

    exit_prog = Value(c_bool, False)
    flag = Value(c_bool, True)

    processA = Process(target=process_A, args=(cv, flag, exit_prog))
    processA.start()

    processB = Process(target=process_B, args=(cv, flag, exit_prog))
    processB.start()

    # Let the threads run for 3 seconds
    time.sleep(3)

    exit_prog.value = True

    processA.join()
    processB.join()