"""Proposed new higher-level threading interfaces. This module is safe for use with 'from threading import *'. It defines the following objects: Lock() A factory function that returns a new primitive lock object. Once a thread has acquired it, subsequent attempts to acquire it block, until it is released; any thread may release it. RLock() A factory function that returns a new reentrant lock object. A reentrant lock must be released by the thread that acquired it. Once a thread has acquired a reentrant lock, the same thread may acquire it again without blocking; the thread must release it once for each time it has acquired it. Condition() A factory function that returns a new condition variable object. A condition variable allows one or more threads to wait until they are notified by another thread. Semaphore() A factory function that returns a new semaphore object. A semaphore manages a counter representing the number of release() calls minus the number of acquire() calls, plus an initial value. The acquire() method blocks if necessary until it can return without making the counter negative. Event() A factory function that returns a new event object. An event manages a flag that can be set to true with the set() method and reset to false with the clear() method. The wait() method blocks until the flag is true. Thread A class that represents a thread of control -- subclassable. currentThread() A function that returns the Thread object for the caller's thread. activeCount() A function that returns the number of currently active threads. enumerate() A function that returns a list of all currently active threads. Detailed interfaces for each of these are documented below in the form of pseudo class definitions. Note that the classes marked as ``do not subclass'' are actually implemented as factory functions; classes are shown here as a way to structure the documentation only. The design of this module is loosely based on Java's threading model. However, where Java makes locks and condition variables basic behavior of every object, they are separate objects in Python. Python's Thread class supports a subset of the behavior of Java's Thread class; currently, there are no priorities, no thread groups, and threads cannot be destroyed, stopped, suspended, resumed, or interrupted. The static methods of Java's Thread class, when implemented, are mapped to module-level functions. All methods described below are executed atomically. """ class Lock: """Primitive lock object. *** DO NOT SUBCLASS THIS CLASS *** A primitive lock is a synchronization primitive that is not owned by a particular thread when locked. In Python, it is currently the lowest level synchronization primitive available, implemented directly by the thread extension module. A primitive lock is in one of two states, ``locked'' or ``unlocked''. It is created in the unlocked state. It has two basic methods, acquire() and release(). When the state is unlocked, acquire() changes the state to locked and returns immediately. When the state is locked, acquire() blocks until a call to release() in another thread changes it to unlocked, then the acquire() call resets it to locked and returns. The release() method should only be called in the locked state; it changes the state to unlocked and returns immediately. When more than one thread is blocked in acquire() waiting for the state to turn to unlocked, only one thread proceeds when a release() call resets the state to unlocked; which one of the waiting threads proceeds is not defined, and may vary across implementations. All methods are executed atomically. """ def acquire(self, blocking=1): """Acquire a lock, blocking or non-blocking. When invoked without arguments, block until the lock is unlocked, then set it to locked, and return. There is no return value in this case. When invoked with the 'blocking' argument set to true, do the same thing as when called without arguments, and return true. When invoked with the 'blocking' argument set to false, do not block. If a call without argument would block, return false immediately; otherwise, do the same thing as when called without arguments, and return true. """ def release(self): """Release a lock. When the lock is locked, reset it to unlocked, and return. If any other threads are blocked waiting for the lock to become unlocked, allow exactly one of them to proceed. Do not call this method when the lock is unlocked. There is no return value. """ class RLock: """Reentrant lock object. *** DO NOT SUBCLASS THIS CLASS *** A reentrant lock is a synchronization primitive that may be acquired multiple times by the same thread. Internally, it uses the concepts of ``owning thread'' and ``recursion level'' in addition to the locked/unlocked state used by primitive locks. In the locked state, some thread owns the lock; in the unlocked state, no thread owns it. To lock the lock, a thread calls its acquire() method; this returns once the thread owns the lock. To unlock the lock, a thread calls its release() method. acquire()/release() call pairs may be nested; only the final release() (i.e. the release() of the outermost pair) resets the lock to unlocked and allows another thread blocked in acquire() to proceed. """ def acquire(self, blocking=1): """Acquire a lock, blocking or non-blocking. When invoked without arguments: if this thread already owns the lock, increment the recursion level by one, and return immediately. Otherwise, if another thread owns the lock, block until the lock is unlocked. Once the lock is unlocked (not owned by any thread), then grab ownership, set the recursion level to one, and return. If more than one thread is blocked waiting until the lock is unlocked, only one at a time will be able to grab ownership of the lock. There is no return value in this case. When invoked with the 'blocking' argument set to true, do the same thing as when called without arguments, and return true. When invoked with the 'blocking' argument set to false, do not block. If a call without argument would block, return false immediately; otherwise, do the same thing as when called without arguments, and return true. """ def release(self): """Release a lock. Only call this method when the calling thread owns the lock. Decrement the recursion level. If after the decrement it is zero, reset the lock to unlocked (not owned by any thread), and if any other threads are blocked waiting for the lock to become unlocked, allow exactly one of them to proceed. If after the decrement the recursion level is still nonzero, the lock remains locked and owned by the calling thread. Do not call this method when the lock is unlocked. There is no return value. """ class Condition: """Synchronized condition variable object. *** DO NOT SUBCLASS THIS CLASS *** A condition variable is always associated with some kind of lock; this can be passed in or one will be created by default. (Passing one in is useful when several condition variables must share the same lock.) A condition variable has acquire() and release() methods that call the corresponding methods of the associated lock. It also has a wait() method, and notify() and notifyAll() methods. These three must only be called when the calling thread has acquired the lock. The wait() method releases the lock, and then blocks until it is awakened by a notifiy() or notifyAll() call for the same condition variable in another thread. Once awakened, it re-acquires the lock and returns. It is also possible to specify a timeout. The notify() method wakes up one of the threads waiting for the condition variable, if any are waiting. The notifyAll() method wakes up all threads waiting for the condition variable. Note: the notify() and notifyAll() methods don't release the lock; this means that the thread or threads awakened will not return from their wait() call immediately, but only when the thread that called notify() or notifyAll() finally relinquishes ownership of the lock. Tip: the typical programming style using condition variables uses the lock to synchronize access to some shared state; threads that are interested in a particular change of state call wait() repeatedly until they see the desired state, while threads that modify the state call notify() or notifyAll() when they change the state in such a way that it could possibly be a desired state for one of the waiters. For example, the following code is a generic producer-consumer situation with unlimited buffer capacity: # Consume one item cv.acquire() while not an_item_is_available(): cv.wait() get_an_available_item() cv.release() # Produce one item cv.acquire() make_an_item_available() cv.notify() cv.release() To choose between notify() and notifyAll(), consider whether one state change can be interesting for only one or several waiting threads. E.g. in a typical producer-consumer situation, adding one item to the buffer only needs to wake up one consumer thread. """ def __init__(self, lock=None): """Constructor. If the lock argument is given and not None, it must be a Lock or RLock object, and it is used as the underlying lock. Otherwise, a new RLock object is created and used as the underlying lock. """ def acquire(self, *args): """Acquire the underlying lock. This method calls the corresponding method on the underlying lock; the return value is whatever that method returns. """ def release(self): """Release the underlying lock. This method calls the corresponding method on the underlying lock; there is no return value. """ def wait(self, timeout=None): """Wait until notified or until a timeout occurs. This must only be called when the calling thread has acquired the lock. This method releases the underlying lock, and then blocks until it is awakened by a notify() or notifyAll() call for the same condition variable in another thread, or until the optional timeout occurs. Once awakened or timed out, it re-acquires the lock and returns. When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). When the underlying lock is an RLock, it is not released using its release() method, since this may not actually unlock the lock when it was acquired() multiple times recursively. Instead, an internal interface of the RLock class is used, which really unlocks it even when it has been recursively acquired several times. Another internal interface is then used to restore the recursion level when the lock is reacquired. """ def notify(self): """Wake up a thread waiting on this condition, if any. This must only be called when the calling thread has acquired the lock. This method wakes up one of the threads waiting for the condition variable, if any are waiting; it is a no-op if no threads are waiting. The current implementation wakes up exactly one thread, if any are waiting. However, it's not safe to rely on this behavior. A future, optimized implementation may occasionally wake up more than one thread. Note: the awakened thread does not actually return from its wait() call until it can reacquire the lock. Since notify() does not release the lock, its caller should. """ def notifyAll(self): """Wake up all threads waiting on this condition. This method acts like notify(), but wakes up all waiting threads instead of one. """ class Semaphore: """Semaphore object. This is one of the oldest synchronization primitives in the history of computer science, invented by the early Dutch computer scientist Edsger W. Dijkstra (he used P() and V() instead of acquire() and release()). A semaphore manages an internal counter which is decremented by each acquire() call and incremented by each release() call. The counter can never go below zero; when acquire() finds that it is zero, it blocks, waiting until some other thread calls release(). """ def __init__(self, value=1): """Constructor. The optional argument gives the initial value for the internal counter; it defaults to 1. """ def acquire(self, blocking=1): """Acquire a semaphore. When invoked without arguments: if the internal counter is larger than zero on entry, decrement it by one and return immediately. If it is zero on entry, block, waiting until some other thread has called release() to make it larger than zero. This is done with proper interlocking so that if multiple acquire() calls are blocked, release() will wake exactly one of them up. The implementation may pick one at random, so the order in which blocked threads are awakened should not be relied on. There is no return value in this case. When invoked with the 'blocking' argument set to true, do the same thing as when called without arguments, and return true. When invoked with the 'blocking' argument set to false, do not block. If a call without argument would block, return false immediately; otherwise, do the same thing as when called without arguments, and return true. """ def release(self): """Release a semaphore. Increment the internal counter by one. When it was zero on entry and another thread is waiting for it to become larger than zero again, wake up that thread. """ class Event: """Event object. This is one of the simplest mechanisms for communication between threads: one thread signals an event and another thread, or threads, wait for it. An event object manages an internal flag that can be set to true with the set() method and reset to false with the clear() method. The wait() method blocks until the flag is true. """ def __init__(self): """Constructor. The internal flag is initially false. """ def isSet(self): """Return true iff the internal flag is true.""" def set(self): """Set the internal flag to true. All threads waiting for it to become true are awakened. Threads that call wait() once the flag is true will not block at all. """ def clear(self): """Reset the internal flag to false. Subsequently, threads calling wait() will block until set() is called to set the internal flag to true again. """ def wait(self, timeout=None): """Block until the internal flag is true. If the internal flag is true on entry, return immediately. Otherwise, block until another thread calls set() to set the flag to true, or until the optional timeout occurs. When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). """ class Thread: """Thread class. *** ONLY OVERRIDE THE __init__() AND run() METHODS OF THIS CLASS *** This class represents an activity that is run in a separate thread of control. There are two ways to specify the activity: by passing a callable object to the constructor, or by overriding the run() method in a subclass. No other methods (except for the constructor) should be overridden in a subclass. Once a thread object is created, its activity must be started by calling the thread's start() method. This invokes the run() method in a separate thread of control. Once the thread's activity is started, the thread is considered 'alive' and 'active' (these concepts are almost, but not quite exactly, the same; their definition is intentionally somewhat vague). It stops being alive and active when its run() method terminates -- either normally, or by raising an unhandled exception. The isAlive() method tests whether the thread is alive. Other threads can call a thread's join() method. This blocks the calling thread until the thread whose join() method is called is terminated. A thread has a name. The name can be passed to the constructor, set with the setName() method, and retrieved with the getName() method. A thread can be flagged as a ``daemon thread''. The significance of this flag is that the entire Python program exits when only daemon threads are left. The initial value is inherited from the creating thread. The flag can be set with the setDaemon() method and retrieved with the getDaemon() method. There is a ``main thread'' object; this corresponds to the initial thread of control in the Python program. It is not a daemon thread. There is the possibility that ``dummy thread objects'' are created. These are thread objects corresponding to ``alien threads''. These are threads of control started outside the threading module, e.g. directly from C code. Dummy thread objects have limited functionality; they are always considered alive, active, and daemonic, and cannot be join()ed. They are never deleted, since it is impossible to detect the termination of alien threads. """ def __init__(self, group=None, target=None, name=None, args=(), kwargs={}): """Thread constructor. This constructor should always be called with keyword arguments. Arguments are: group Should be None; reserved for future extension when a ThreadGroup class is implemented. target Callable object to be invoked by the run() method. Defaults to None, meaning nothing is called. name The thread name. By default, a unique name is constructed of the form ``Thread-N'' where N is a small decimal number. args Argument tuple for the target invocation. Defaults to (). kwargs Keyword argument dictionary for the target invocation. Defaults to {}. If the subclass overrides the constructor, it must make sure to invoke the base class constructor (Thread.__init__()) before doing anything else to the thread. """ def start(self): """Start the thread's activity. This must be called at most once per thread object. It arranges for the object's run() method to be invoked in a separate thread of control. """ def run(self): """Method representing the thread's activity. You may override this method in a subclass. The standard run() method invokes the callable object passed as the 'target' argument, if any, with sequential and keyword arguments taken from the 'args' and 'kwargs' arguments, respectively. """ def join(self, timeout=None): """Wait until the thread terminates. This blocks the calling thread until the thread whose join() method is called terminates -- either normally or through an unhandled exception -- or until the optional timeout occurs. When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). A thread can be join()ed many times. A thread cannot join itself because this would cause a deadlock. It is an error to attempt to join() a thread before it has been started. """ def getName(self): """Return the thread's name.""" def setName(self, name): """Set the thread's name. The name is a string used for identification purposes only. It has no semantics. Multiple threads may be given the same name. The initial name is set by the constructor. """ def isAlive(self): """Return whether the thread is alive. Roughly, a thread is alive from the moment the start() method returns until its run() method terminates. """ def isDaemon(self): """Return the thread's daemon flag.""" def setDaemon(self, daemonic): """Set the thread's daemon flag (a Boolean). This must be called before start() is called. The initial value is inherited from the creating thread. The entire Python program exits when no active non-daemon threads are left. """ # Module-level functions: def currentThread(): """Return the current Thread object. This function returns the Thread object corresponding to the caller's thread of control. If the caller's thread of control was not created through the threading module, a dummy thread object with limited functionality is returned. """ def activeCount(): """Return the number of currently active Thread objects. The returned count is equal to the length of the list returned by enumerate(). """ def enumerate(): """Return a list of all currently active Thread objects. The list includes daemonic threads, dummy thread objects created by currentThread(), and the main thread. It excludes terminated threads and threads that have not yet been started. """