This recipe presents the sync class and an example usage. The primary ingredient in this recipe are the locks from the thread module. The idea that is followed is quite simple. You have a room with a front door and a back door. Threads walk into the front door and out the back door. Your room only has a certain capacity for threads (specified on construction of the room [sync object]) and the back door is closed. When the room is full, the front door is closed; and the back door is opened. When the room has been emptied, the front door is opened; and the back door is closed. In this way, you know that all of your threads pile into a room; and that when they all arrive, they will all exit concurrently with each other. The example function shows two different sync objects being used in different roles.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
import thread class sync: def __init__(self, threads): self.__threads = threads self.__count = 0 self.__main = thread.allocate_lock() self.__exit = thread.allocate_lock() self.__exit.acquire() def sync(self): self.__main.acquire() self.__count += 1 if self.__count < self.__threads: self.__main.release() else: self.__exit.release() self.__exit.acquire() self.__count -= 1 if self.__count > 0: self.__exit.release() else: self.__main.release() def example(): def get_input(share): while share: share = raw_input('Please say something.\n') share.sync() share.sync() def do_output(share): while share: share.sync() print 'You said, "%s"' % share share.sync() share = [True, None, sync(2), sync(3)] thread.start_new_thread(get_input, (share,)) thread.start_new_thread(do_output, (share,)) import time; time.sleep(60) share = False share.sync() if __name__ == '__main__': example()
Why would someone want to use the sync class? Sometimes when writing a multi-threaded application, it is desireable for your threads to eventually syncronize with each other so that they are all at the same point in execution. This may be somewhat difficult, especially without a special mechanism to do this for you. This is where the sync class comes into play. A sync object can be shared by several threads; and if it knows how many objects it is being shared with, it can automatically syncronize those threads when properly used. As shown in the example function, threads that wish to syncronize with other threads call the sync function on the sync object; and syncronization will automatically be accomplished (assuming that the other threads using the sync object also call the sync function as well). This is just a simple implementation of the syncronization concept and could be expanded more by adding more options to it (such as maximum blocking times et cetera). If you are into writing threaded programs, hopefully this will be a useful recipe for you.