threading
--- 基于线程的并发¶
源代码: Lib/threading.py
这个模块在较低级的模块 _thread
基础上建立较高级的线程接口。参见: queue
模块。
在 3.7 版更改: 这个模块曾经为可选项,但现在总是可用。
注解
虽然他们没有在下面列出,这个模块仍然支持Python 2.x系列的这个模块下以 camelCase
(驼峰法)命名的方法和函数。
这个模块定义了以下函数:
-
threading.
active_count
()¶ 返回当前存活的线程类
Thread
对象。返回的计数等于enumerate()
返回的列表长度。
-
threading.
get_ident
()¶ 返回当前线程的 “线程标识符”。它是一个非零的整数。它的值没有直接含义,主要是用作 magic cookie,比如作为含有线程相关数据的字典的索引。线程标识符可能会在线程退出,新线程创建时被复用。
3.3 新版功能.
-
threading.
enumerate
()¶ 以列表形式返回当前所有存活的
Thread
对象。该列表包含守护线程,current_thread()
创建的虚拟线程对象和主线程。它包含了已终结的线程和尚未开始的线程。
-
threading.
settrace
(func)¶ 为所有
threading
模块开始的线程设置追踪函数。在每个线程的run()
方法被调用前,func 会被传递给sys.settrace()
。
-
threading.
setprofile
(func)¶ 为所有
threading
模块开始的线程设置性能测试函数。在每个线程的run()
方法被调用前,func 会被传递给sys.setprofile()
。
-
threading.
stack_size
([size])¶ 返回创建线程时用的堆栈大小。可选参数 size 指定之后新建的线程的堆栈大小,而且一定要是0(根据平台或者默认配置)或者最小是32,768(32KiB)的一个正整数。如果 size 没有指定,默认是0。如果不支持改变线程堆栈大小,会抛出
RuntimeError
错误。如果指定的堆栈大小不合法,会抛出ValueError
错误并且不会修改堆栈大小。32KiB是当前最小的能保证解释器有足够堆栈空间的堆栈大小。需要注意的是部分平台对于堆栈大小会有特定的限制,例如要求大于32KiB的堆栈大小或者需要根据系统内存页面的整数倍进行分配 - 应当查阅平台文档有关详细信息(4KiB页面比较普遍,在没有更具体信息的情况下,建议的方法是使用4096的倍数作为堆栈大小)。可用性: Windows,具有 POSIX 线程的系统。
这个模块同时定义了以下常量:
-
threading.
TIMEOUT_MAX
¶ 阻塞函数(
Lock.acquire()
,RLock.acquire()
,Condition.wait()
, ...)中形参 timeout 允许的最大值。传入超过这个值的 timeout 会抛出OverflowError
异常。3.2 新版功能.
这个模块定义了许多类,详见以下部分。
这个模块的设计大部分基于Java的线程模型。Java令锁和条件变量成为每个对象基本行为,但是在Python中它们是独立的对象。Python的 Thread
类支持Java的线程类的行为子集;目前没有优先级,没有线程组而且线程不能被销毁,停止,暂停,回复或者中断。当实现Java的线程静态方法时,映射到模块级别的函数。
下列描述的方法都是自动执行的。
线程本地数据¶
线程本地数据是特定线程的数据。管理线程本地数据,只需要创建一个 local
(或者一个子类型)的实例并在实例中储存属性:
mydata = threading.local()
mydata.x = 1
在不同的线程中,实例的值会不同。
-
class
threading.
local
¶ 一个代表线程本地数据的类。
更多相关细节和大量示例,参见
_threading_local
模块的文档字符串。
线程对象¶
The Thread
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. In other words, only override the
__init__()
and run()
methods of this class.
当线程对象一但被创建,其活动一定会因调用线程的 start()
方法开始。这会在独立的控制线程调用 run()
方法。
一旦线程活动开始,该线程会被认为是 '存活的' 。当它的 run()
方法终结了(不管是正常的还是抛出未被处理的异常),就不是'存活的'。 is_alive()
方法用于检查线程是否存活。
其他线程可以调用一个线程的 join()
方法。这会阻塞调用该方法的线程,直到被调用 join()
方法的线程终结。
线程有名字。名字可以传递给构造函数,也可以通过 name
属性读取或者修改。
一个线程可以被标记成一个 "守护线程" 。这个标志的意义是,只有守护线程都终结,整个Python程序才会退出。初始值继承于创建线程。这个标志可以通过 daemon
特征属性或者 守护 构造函数参数来设置。
注解
守护线程在程序关闭时会突然关闭。他们的资源(例如已经打开的文档,数据库事务等等)可能没有被正确释放。如果你想你的线程正常停止,设置他们成为非守护模式并且使用合适的信号机制,例如: Event
。
有个 "主线程" 对象;这对应Python程序里面初始的控制线程。它不是一个守护线程。
"虚拟线程对象" 是可以被创建的。这些是对应于“外部线程”的线程对象,它们是在线程模块外部启动的控制线程,例如直接来自C代码。虚拟线程对象功能受限;他们总是被认为是存活的和守护模式,不能被 join()
。因为无法检测外来线程的终结,它们永远不会被删除。
-
class
threading.
Thread
(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)¶ 调用这个构造函数时,必需带有关键字参数。参数如下:
group 应该为
None
;为了日后扩展ThreadGroup
类实现而保留。target 是用于
run()
方法调用的可调用对象。默认是None
,表示不需要调用任何方法。name 是线程名称。默认情况下,由 "Thread-N" 格式构成一个唯一的名称,其中 N 是小的十进制数。
args 是用于调用目标函数的参数元组。默认是
()
。kwargs 是用于调用目标函数的关键字参数字典。默认是
{}
。如果不是
None
,不管当前线程是否守护模式,显式设置成 守护模式 。如果是None
(默认),守护模式特征属性继承自当前线程。如果子类型重载了构造函数,它一定要确保在做任何事前,先发起调用基类构造器(
Thread.__init__()
)。在 3.3 版更改: 加入 daemon 参数。
-
start
()¶ 开始线程活动。
它在一个线程里最多只能被调用一次。它安排对象的
run()
方法在一个独立的控制进程中调用。如果同一个线程对象中调用这个方法的次数大于一次,会抛出
RuntimeError
。
-
run
()¶ 代表线程活动的方法。
你可以在子类型里重载这个方法。标准的
run()
方法调用一个传递给对象构造函数的可调用对象,如果有,分别从 args 和 kwargs 参数中获取顺序和关键字参数。
-
join
(timeout=None)¶ 等待,直到线程终结。这会阻塞调用这个方法的线程,直到被调用
join()
的线程终结 -- 不管是正常终结还是抛出未处理异常 -- 或者直到发生超时,超时选项是可选的。当 timeout 参数存在而且不是
None
时,它应该是一个用于指定操作超时的以秒为单位的浮点数(或者分数)。因为join()
总是返回None
,所以你一定要在join()
后调用is_alive()
才能判断是否发生超时 -- 如果线程仍然存货,则join()
超时。当 timeout 参数不存在或者是
None
,这个操作会阻塞直到线程终结。一个线程可以被
join()
很多次。如果尝试加入当前线程会导致死锁,
join()
会抛出RuntimeError
。如果尝试join()
一个尚未开始的线程,也会抛出相同的异常。
-
name
¶ 只用于识别的字符串。它没有语义。多个线程可以赋予相同的名称。 初始名称由构造函数设置。
-
ident
¶ The 'thread identifier' of this thread or
None
if the thread has not been started. This is a nonzero integer. See theget_ident()
function. Thread identifiers may be recycled when a thread exits and another thread is created. The identifier is available even after the thread has exited.
-
is_alive
()¶ 返回线程是否存活。
This method returns
True
just before therun()
method starts until just after therun()
method terminates. The module functionenumerate()
returns a list of all alive threads.
-
daemon
¶ A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before
start()
is called, otherwiseRuntimeError
is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default todaemon
=False
.The entire Python program exits when no alive non-daemon threads are left.
-
CPython implementation detail: In CPython, due to the Global Interpreter Lock, only one thread
can execute Python code at once (even though certain performance-oriented
libraries might overcome this limitation).
If you want your application to make better use of the computational
resources of multi-core machines, you are advised to use
multiprocessing
or concurrent.futures.ProcessPoolExecutor
.
However, threading is still an appropriate model if you want to run
multiple I/O-bound tasks simultaneously.
锁对象¶
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. If an attempt is made to release an unlocked lock, a
RuntimeError
will be raised.
Locks also support the context management protocol.
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.
所有方法都是自动运行的。
-
class
threading.
Lock
¶ The class implementing primitive lock objects. Once a thread has acquired a lock, subsequent attempts to acquire it block, until it is released; any thread may release it.
需要注意的是
Lock
其实是一个工厂函数,返回平台支持的具体锁类中最有效的版本的实例。-
acquire
(blocking=True, timeout=-1)¶ 获得锁,阻塞或非阻塞的。
When invoked with the blocking argument set to
True
(the default), block until the lock is unlocked, then set it to locked and returnTrue
.When invoked with the blocking argument set to
False
, do not block. If a call with blocking set toTrue
would block, returnFalse
immediately; otherwise, set the lock to locked and returnTrue
.When invoked with the floating-point timeout argument set to a positive value, block for at most the number of seconds specified by timeout and as long as the lock cannot be acquired. A timeout argument of
-1
specifies an unbounded wait. It is forbidden to specify a timeout when blocking is false.The return value is
True
if the lock is acquired successfully,False
if not (for example if the timeout expired).在 3.2 版更改: 新的 timeout 形参。
在 3.2 版更改: Lock acquisition can now be interrupted by signals on POSIX if the underlying threading implementation supports it.
-
release
()¶ Release a lock. This can be called from any thread, not only the thread which has acquired the 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.
When invoked on an unlocked lock, a
RuntimeError
is raised.没有返回值。
-
递归锁对象¶
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()
(the
release()
of the outermost pair) resets the lock to unlocked and
allows another thread blocked in acquire()
to proceed.
Reentrant locks also support the context management protocol.
-
class
threading.
RLock
¶ This class implements reentrant lock objects. 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.
Note that
RLock
is actually a factory function which returns an instance of the most efficient version of the concrete RLock class that is supported by the platform.-
acquire
(blocking=True, timeout=-1)¶ 获得锁,阻塞或非阻塞的。
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 an argument would block, return false immediately; otherwise, do the same thing as when called without arguments, and return true.
When invoked with the floating-point timeout argument set to a positive value, block for at most the number of seconds specified by timeout and as long as the lock cannot be acquired. Return true if the lock has been acquired, false if the timeout has elapsed.
在 3.2 版更改: 新的 timeout 形参。
-
release
()¶ Release a lock, decrementing 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.
Only call this method when the calling thread owns the lock. A
RuntimeError
is raised if this method is called when the lock is unlocked.没有返回值。
-
Condition Objects¶
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. The lock is part of the condition object: you don't have to track it separately.
A condition variable obeys the context management protocol:
using the with
statement acquires the associated lock for the duration of
the enclosed block. The acquire()
and
release()
methods also call the corresponding methods of
the associated lock.
Other methods must be called with the associated lock held. The
wait()
method releases the lock, and then blocks until
another thread awakens it by calling notify()
or
notify_all()
. Once awakened, wait()
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 notify_all()
method wakes up all threads waiting for the condition variable.
Note: the notify()
and notify_all()
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 notify_all()
finally relinquishes ownership of the lock.
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 notify_all()
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
with cv:
while not an_item_is_available():
cv.wait()
get_an_available_item()
# Produce one item
with cv:
make_an_item_available()
cv.notify()
The while
loop checking for the application's condition is necessary
because wait()
can return after an arbitrary long time,
and the condition which prompted the notify()
call may
no longer hold true. This is inherent to multi-threaded programming. The
wait_for()
method can be used to automate the condition
checking, and eases the computation of timeouts:
# Consume an item
with cv:
cv.wait_for(an_item_is_available)
get_an_available_item()
To choose between notify()
and notify_all()
,
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.
-
class
threading.
Condition
(lock=None)¶ This class implements condition variable objects. A condition variable allows one or more threads to wait until they are notified by another thread.
If the lock argument is given and not
None
, it must be aLock
orRLock
object, and it is used as the underlying lock. Otherwise, a newRLock
object is created and used as the underlying lock.在 3.3 版更改: changed from a factory function to a class.
-
acquire
(*args)¶ Acquire the underlying lock. This method calls the corresponding method on the underlying lock; the return value is whatever that method returns.
-
release
()¶ Release the underlying lock. This method calls the corresponding method on the underlying lock; there is no return value.
-
wait
(timeout=None)¶ Wait until notified or until a timeout occurs. If the calling thread has not acquired the lock when this method is called, a
RuntimeError
is raised.This method releases the underlying lock, and then blocks until it is awakened by a
notify()
ornotify_all()
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 itsrelease()
method, since this may not actually unlock the lock when it was acquired multiple times recursively. Instead, an internal interface of theRLock
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.The return value is
True
unless a given timeout expired, in which case it isFalse
.在 3.2 版更改: Previously, the method always returned
None
.
-
wait_for
(predicate, timeout=None)¶ Wait until a condition evaluates to true. predicate should be a callable which result will be interpreted as a boolean value. A timeout may be provided giving the maximum time to wait.
This utility method may call
wait()
repeatedly until the predicate is satisfied, or until a timeout occurs. The return value is the last return value of the predicate and will evaluate toFalse
if the method timed out.Ignoring the timeout feature, calling this method is roughly equivalent to writing:
while not predicate(): cv.wait()
Therefore, the same rules apply as with
wait()
: The lock must be held when called and is re-acquired on return. The predicate is evaluated with the lock held.3.2 新版功能.
-
notify
(n=1)¶ By default, wake up one thread waiting on this condition, if any. If the calling thread has not acquired the lock when this method is called, a
RuntimeError
is raised.This method wakes up at most n of the threads waiting for the condition variable; it is a no-op if no threads are waiting.
The current implementation wakes up exactly n threads, if at least n threads are waiting. However, it's not safe to rely on this behavior. A future, optimized implementation may occasionally wake up more than n threads.
Note: an awakened thread does not actually return from its
wait()
call until it can reacquire the lock. Sincenotify()
does not release the lock, its caller should.
-
notify_all
()¶ Wake up all threads waiting on this condition. This method acts like
notify()
, but wakes up all waiting threads instead of one. If the calling thread has not acquired the lock when this method is called, aRuntimeError
is raised.
-
Semaphore Objects¶
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 the names 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()
.
Semaphores also support the context management protocol.
-
class
threading.
Semaphore
(value=1)¶ This class implements semaphore objects. A semaphore manages an atomic counter representing the number of
release()
calls minus the number ofacquire()
calls, plus an initial value. Theacquire()
method blocks if necessary until it can return without making the counter negative. If not given, value defaults to 1.The optional argument gives the initial value for the internal counter; it defaults to
1
. If the value given is less than 0,ValueError
is raised.在 3.3 版更改: changed from a factory function to a class.
-
acquire
(blocking=True, timeout=None)¶ Acquire a semaphore.
When invoked without arguments:
- If the internal counter is larger than zero on entry, decrement it by one and return true immediately.
- If the internal counter is zero on entry, block until awoken by a call to
release()
. Once awoken (and the counter is greater than 0), decrement the counter by 1 and return true. Exactly one thread will be awoken by each call torelease()
. The order in which threads are awoken should not be relied on.
When invoked with blocking set to false, do not block. If a call without an argument would block, return false immediately; otherwise, do the same thing as when called without arguments, and return true.
When invoked with a timeout other than
None
, it will block for at most timeout seconds. If acquire does not complete successfully in that interval, return false. Return true otherwise.在 3.2 版更改: 新的 timeout 形参。
-
release
()¶ Release a semaphore, incrementing 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
threading.
BoundedSemaphore
(value=1)¶ Class implementing bounded semaphore objects. A bounded semaphore checks to make sure its current value doesn't exceed its initial value. If it does,
ValueError
is raised. In most situations semaphores are used to guard resources with limited capacity. If the semaphore is released too many times it's a sign of a bug. If not given, value defaults to 1.在 3.3 版更改: changed from a factory function to a class.
Semaphore
Example¶
Semaphores are often used to guard resources with limited capacity, for example, a database server. In any situation where the size of the resource is fixed, you should use a bounded semaphore. Before spawning any worker threads, your main thread would initialize the semaphore:
maxconnections = 5
# ...
pool_sema = BoundedSemaphore(value=maxconnections)
Once spawned, worker threads call the semaphore's acquire and release methods when they need to connect to the server:
with pool_sema:
conn = connectdb()
try:
# ... use connection ...
finally:
conn.close()
The use of a bounded semaphore reduces the chance that a programming error which causes the semaphore to be released more than it's acquired will go undetected.
事件对象¶
This is one of the simplest mechanisms for communication between threads: one thread signals an event and other 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.
-
class
threading.
Event
¶ Class implementing event objects. An event manages a flag that can be set to true with the
set()
method and reset to false with theclear()
method. Thewait()
method blocks until the flag is true. The flag is initially false.在 3.3 版更改: changed from a factory function to a class.
-
is_set
()¶ Return true if and only if the internal flag is true.
-
set
()¶ 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.
-
clear
()¶ Reset the internal flag to false. Subsequently, threads calling
wait()
will block untilset()
is called to set the internal flag to true again.
-
wait
(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).This method returns true if and only if the internal flag has been set to true, either before the wait call or after the wait starts, so it will always return
True
except if a timeout is given and the operation times out.在 3.1 版更改: Previously, the method always returned
None
.
-
Timer Objects¶
This class represents an action that should be run only after a certain amount
of time has passed --- a timer. Timer
is a subclass of Thread
and as such also functions as an example of creating custom threads.
Timers are started, as with threads, by calling their start()
method. The timer can be stopped (before its action has begun) by calling the
cancel()
method. The interval the timer will wait before
executing its action may not be exactly the same as the interval specified by
the user.
例如:
def hello():
print("hello, world")
t = Timer(30.0, hello)
t.start() # after 30 seconds, "hello, world" will be printed
-
class
threading.
Timer
(interval, function, args=None, kwargs=None)¶ Create a timer that will run function with arguments args and keyword arguments kwargs, after interval seconds have passed. If args is
None
(the default) then an empty list will be used. If kwargs isNone
(the default) then an empty dict will be used.在 3.3 版更改: changed from a factory function to a class.
-
cancel
()¶ Stop the timer, and cancel the execution of the timer's action. This will only work if the timer is still in its waiting stage.
-
壁垒对象¶
3.2 新版功能.
This class provides a simple synchronization primitive for use by a fixed number
of threads that need to wait for each other. Each of the threads tries to pass
the barrier by calling the wait()
method and will block until
all of the threads have made their wait()
calls. At this point,
the threads are released simultaneously.
The barrier can be reused any number of times for the same number of threads.
As an example, here is a simple way to synchronize a client and server thread:
b = Barrier(2, timeout=5)
def server():
start_server()
b.wait()
while True:
connection = accept_connection()
process_server_connection(connection)
def client():
b.wait()
while True:
connection = make_connection()
process_client_connection(connection)
-
class
threading.
Barrier
(parties, action=None, timeout=None)¶ Create a barrier object for parties number of threads. An action, when provided, is a callable to be called by one of the threads when they are released. timeout is the default timeout value if none is specified for the
wait()
method.-
wait
(timeout=None)¶ Pass the barrier. When all the threads party to the barrier have called this function, they are all released simultaneously. If a timeout is provided, it is used in preference to any that was supplied to the class constructor.
The return value is an integer in the range 0 to parties -- 1, different for each thread. This can be used to select a thread to do some special housekeeping, e.g.:
i = barrier.wait() if i == 0: # Only one thread needs to print this print("passed the barrier")
If an action was provided to the constructor, one of the threads will have called it prior to being released. Should this call raise an error, the barrier is put into the broken state.
If the call times out, the barrier is put into the broken state.
This method may raise a
BrokenBarrierError
exception if the barrier is broken or reset while a thread is waiting.
-
reset
()¶ Return the barrier to the default, empty state. Any threads waiting on it will receive the
BrokenBarrierError
exception.Note that using this function may can require some external synchronization if there are other threads whose state is unknown. If a barrier is broken it may be better to just leave it and create a new one.
-
abort
()¶ Put the barrier into a broken state. This causes any active or future calls to
wait()
to fail with theBrokenBarrierError
. Use this for example if one of the needs to abort, to avoid deadlocking the application.It may be preferable to simply create the barrier with a sensible timeout value to automatically guard against one of the threads going awry.
-
parties
¶ The number of threads required to pass the barrier.
-
n_waiting
¶ The number of threads currently waiting in the barrier.
-
broken
¶ A boolean that is
True
if the barrier is in the broken state.
-
-
exception
threading.
BrokenBarrierError
¶ This exception, a subclass of
RuntimeError
, is raised when theBarrier
object is reset or broken.
Using locks, conditions, and semaphores in the with
statement¶
All of the objects provided by this module that have acquire()
and
release()
methods can be used as context managers for a with
statement. The acquire()
method will be called when the block is
entered, and release()
will be called when the block is exited. Hence,
the following snippet:
with some_lock:
# do something...
相当于:
some_lock.acquire()
try:
# do something...
finally:
some_lock.release()
Currently, Lock
, RLock
, Condition
,
Semaphore
, and BoundedSemaphore
objects may be used as
with
statement context managers.