Home > Net >  How would I use Pythons thread class to sync operations across threads
How would I use Pythons thread class to sync operations across threads

Time:03-31

I was just reading through the threading API in Python 3 and I don't see a method of syncing threads. In my case I'm creating performance testing in a Server and Client environment so I might want to use the thread class call this test with N users:

def tDoTest( ):
    doSync()   # Wait for all thread creation
    doLogin()
    doSync()   # Wait for all users to login
    startTest()
    create100Rows()
    endTest()
    doSync()   # Wait for completion
    doLogout()

I was hoping there was a built in way to handle this that I missed.

CodePudding user response:

You could use a blocking queue.

import queue

q = queue.Queue()

If you want one thread to wait for all members of a group of three other threads to do some task, the waiting thread could get() three tokens from the queue:

for i in range(3):
    q.get()

Each of the three awaited threads could signify that it has completed its task by putting an informationless token into the queue:

q.put(())

The waiting thread will not exit its for loop until it has collected all three tokens.


You could wrap it up in a class:

import queue
import threading
import time

class CountdownLatch:
    def __init__(self, N):
        self.N = N
        self.q = queue.Queue()

    def check_in(self):
        self.q.put(())

    def await_all_checkins(self):
        for i in range(self.N):
            self.q.get()

def demo_CountDownLatch():
    cdl = CountdownLatch(3)
    def task(cdl,delay):
        time.sleep(delay)
        print(delay)
        cdl.check_in()

    threading.Thread(target=task, args=(cdl,2.0)).start()
    threading.Thread(target=task, args=(cdl,1.5)).start()
    threading.Thread(target=task, args=(cdl,1.0)).start()
    cdl.await_all_checkins()
    print("nighty night.")

if __name__ == "__main__":
    demo_CountDownLatch()

CodePudding user response:

OK after a bunch of searching this is the answer. Never expected this functionality to be named Barrier(). The is a built in function for it.

b = Barrier(2, timeout=5)

def doSync():
    ct  = threading.currentThread()
    b.wait( )
    print('Sync done: '   ct.getName())

The output looks like as expected now:

0.75
1.0
Sync done: 1
Sync done: 2
0.75
1.0
Sync done: 1
Sync done: 2
0.75
1.0
Sync done: 1
Sync done: 2
  • Related