Search code examples
pythoneventssynchronizationpython-multithreading

how to sync two contantly running threads using event?


I am trying to run a few lines in thread1 according to an event from thread2. Both threads run constantly in a "while True" loop. The problem is that I can't seem to run the requied lines ONLY when the event is occuring.

BTW, both threads use a shared resouce (list) and can be synched using Lock method. This also did not work for me.

frames_list = []
new_frame = Event()
result = 0


def thr1():
    global frames_list
    global frames_list_max_size
    global result
    while True:
        new_frame.set()
        result = result + 1
        new_frame.clear()


def thr2():
    global result
    while True:
        new_frame.wait()
        print(datetime.datetime.now())
        print(result)


threads = []
for func in [thr1, thr2]:
    threads.append(Thread(target=func))
    threads[-1].start()

for thread in threads:
    thread.join()

result for example:

2019-10-19 22:35:34.150852
1710538
2019-10-19 22:35:34.173803
1722442
2019-10-19 22:35:34.197736
1737844
2019-10-19 22:35:34.214684
1740218
2019-10-19 22:35:34.220664
1749776

I would expect: 1. time diff between every print would be 1 sec. 2. result would increment by 1 for every print.


Solution

  • You can't solve this problem using one Event object, but you can do this using two Event objects:

    1. One to notify that the result variable was changed.
    2. One to notify that the new value of the result variable was consumed.

    Modified code:

    import time
    
    frames_list = []
    new_frame = Event()
    new_frame_consumed = Event()
    result = 0
    
    
    def thr1():
        global frames_list
        global frames_list_max_size
        global result
        while True:
            result = result + 1
            time.sleep(1)
            new_frame.set()
            new_frame_consumed.wait()
            new_frame_consumed.clear()
    
    
    def thr2():
        global result
        while True:
            new_frame.wait()
            new_frame.clear()
            print(datetime.datetime.now())
            print(result)
            new_frame_consumed.set()
    
    
    threads = []
    for func in [thr1, thr2]:
        threads.append(Thread(target=func))
        threads[-1].start()
    
    for thread in threads:
        thread.join()