Search code examples
pythonmultithreadingvariablesglobalpython-multithreading

How can I control three different threads using threading in Python?


I have thread1, thread2 and thread3, global variable x and three different functions to increment x,

import threading
import time

#check = threading.Condition()
x=1

def add_by1():
    global x
    x+=1
    time.sleep(1)
    print(x)
    

def add_by2():
    x+=2
    time.sleep(1)
    print(x)

def add_by3():
    x+=3
    time.sleep(1)
    print(x)

if __name__==__main__:
    threading.Thread(target=add_by1).start()
    threading.Thread(target=add_by2).start()
    threading.Thread(target=add_by3).start()

# I want the output should print.. 
"""
2
4
7
8
10
13
14
16
19
and so on ..
"""

can I use the Condition(), if so how? can I use other threading classes?, how would I insert some codes on these functions?


Solution

  • I guess this approach is reliable. You can synchronize your threads using three lock objects - one for each.

    The way this setup works is each thread acquires its lock and after doing its job, it releases next thread's lock! IOW, add_by1 releases thread_lock_two, add_by2 releases thread_lock_three and lastly add_by3 releases thread_lock_one.

    Initially you need to acquire thread_lock_two and thread_lock_three's lock so that only the first thread does its job.

    Whenever the condition is met (you said x == 20), each thread should again release next thread's lock also return !

    import threading
    from time import sleep
    
    x = 1
    
    thread_lock_one = threading.Lock()
    thread_lock_two = threading.Lock()
    thread_lock_three = threading.Lock()
    
    thread_lock_two.acquire()
    thread_lock_three.acquire()
    
    
    def add_by1():
        global x
        while True:
            thread_lock_one.acquire()
            if x >= 20:
                thread_lock_two.release()
                return
            x += 1
            print(x)
            sleep(0.6)
            thread_lock_two.release()
    
    
    def add_by2():
        global x
        while True:
            thread_lock_two.acquire()
            if x >= 20:
                thread_lock_three.release()
                return
            x += 2
            print(x)
            sleep(0.6)
            thread_lock_three.release()
    
    
    def add_by3():
        global x
        while True:
            thread_lock_three.acquire()
            if x >= 20:
                thread_lock_one.release()
                return
            x += 3
            print(x)
            sleep(0.6)
            thread_lock_one.release()
    
    
    if __name__ == "__main__":
        threading.Thread(target=add_by1).start()
        threading.Thread(target=add_by2).start()
        threading.Thread(target=add_by3).start()
    

    output:

    2
    4
    7
    8
    10
    13
    14
    16
    19
    20