threading --- 執行緒層級的平行處理¶
原始碼:Lib/threading.py
此模組在較低層的 _thread 模組之上,建構了較高層的執行緒(threading)介面。
可用性: not WASI.
此模組在 WebAssembly 平台上不起作用或無法使用。更多資訊請參閱 WebAssembly 平台。
介紹¶
模組 threading 提供了一種方式,能在單一進程(process)中同時執行多個 執行緒 (一個進程中的較小執行單元)。它允許創造與管理執行緒,使多個任務可以平行執行並共享同一個記憶體空間。當任務屬於 I/O 密集型(I/O bound)時,執行緒特別有用,例如檔案操作或網路請求,因為這類任務的大部分時間都花在等待外部資源。
模組 threading 的一個典型使用情境是管理一個工作執行緒(worker threads)池,讓多個任務能夠同時被處理。以下是一個使用 Thread: 來創造並啟動執行緒的基本範例:
import threading
import time
def crawl(link, delay=3):
print(f"crawl started for {link}")
time.sleep(delay) # Blocking I/O (simulating a network request)
print(f"crawl ended for {link}")
links = [
"https://python.org",
"https://docs.python.org",
"https://peps.python.org",
]
# Start threads for each link
threads = []
for link in links:
# Using `args` to pass positional arguments and `kwargs` for keyword arguments
t = threading.Thread(target=crawl, args=(link,), kwargs={"delay": 2})
threads.append(t)
# Start each thread
for t in threads:
t.start()
# Wait for all threads to finish
for t in threads:
t.join()
在 3.7 版的變更: This module used to be optional, it is now always available.
也參考
concurrent.futures.ThreadPoolExecutor offers a higher level interface
to push tasks to a background thread without blocking execution of the
calling thread, while still being able to retrieve their results when needed.
queue provides a thread-safe interface for exchanging data between
running threads.
asyncio offers an alternative approach to achieving task level
concurrency without requiring the use of multiple operating system threads.
備註
In the Python 2.x series, this module contained camelCase names
for some methods and functions. These are deprecated as of Python 3.10,
but they are still supported for compatibility with Python 2.5 and lower.
CPython 實作細節: 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.
GIL and performance considerations¶
Unlike the multiprocessing module, which uses separate processes to
bypass the global interpreter lock (GIL), the threading module operates
within a single process, meaning that all threads share the same memory space.
However, the GIL limits the performance gains of threading when it comes to
CPU-bound tasks, as only one thread can execute Python bytecode at a time.
Despite this, threads remain a useful tool for achieving concurrency in many
scenarios.
As of Python 3.13, free-threaded builds can disable the GIL, enabling true parallel execution of threads, but this feature is not available by default (see PEP 703).
Reference¶
此模組定義了以下函式:
- threading.active_count()¶
Return the number of
Threadobjects currently alive. The returned count is equal to the length of the list returned byenumerate().The function
activeCountis a deprecated alias for this function.
- threading.current_thread()¶
Return the current
Threadobject, corresponding to the caller's thread of control. If the caller's thread of control was not created through thethreadingmodule, a dummy thread object with limited functionality is returned.currentThread函式是此函式的已棄用別名。
- threading.excepthook(args, /)¶
處理由
Thread.run()引發且未被捕捉到的例外。args 引數有下列屬性:
exc_type:例外型別。
exc_value: Exception value, can be
None.exc_traceback: Exception traceback, can be
None.thread:引發例外的執行緒,可以是
None。
If exc_type is
SystemExit, the exception is silently ignored. Otherwise, the exception is printed out onsys.stderr.如果這個函式引發例外,則會呼叫
sys.excepthook()來處理它。threading.excepthook()can be overridden to control how uncaught exceptions raised byThread.run()are handled.Storing exc_value using a custom hook can create a reference cycle. It should be cleared explicitly to break the reference cycle when the exception is no longer needed.
Storing thread using a custom hook can resurrect it if it is set to an object which is being finalized. Avoid storing thread after the custom hook completes to avoid resurrecting objects.
也參考
sys.excepthook()處理未被捕捉到的例外。在 3.8 版被加入.
- threading.__excepthook__¶
Holds the original value of
threading.excepthook(). It is saved so that the original value can be restored in case they happen to get replaced with broken or alternative objects.在 3.10 版被加入.
- threading.get_ident()¶
Return the 'thread identifier' of the current thread. This is a nonzero integer. Its value has no direct meaning; it is intended as a magic cookie to be used e.g. to index a dictionary of thread-specific data. Thread identifiers may be recycled when a thread exits and another thread is created.
在 3.3 版被加入.
- threading.get_native_id()¶
Return the native integral Thread ID of the current thread assigned by the kernel. This is a non-negative integer. Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS).
可用性: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD, GNU/kFreeBSD.
在 3.8 版被加入.
在 3.13 版的變更: 新增對 GNU/kFreeBSD 的支援。
- threading.enumerate()¶
Return a list of all
Threadobjects currently active. The list includes daemonic threads and dummy thread objects created bycurrent_thread(). It excludes terminated threads and threads that have not yet been started. However, the main thread is always part of the result, even when terminated.
- threading.main_thread()¶
Return the main
Threadobject. In normal conditions, the main thread is the thread from which the Python interpreter was started.在 3.4 版被加入.
- threading.settrace(func)¶
Set a trace function for all threads started from the
threadingmodule. The func will be passed tosys.settrace()for each thread, before itsrun()method is called.
- threading.settrace_all_threads(func)¶
Set a trace function for all threads started from the
threadingmodule and all Python threads that are currently executing.The func will be passed to
sys.settrace()for each thread, before itsrun()method is called.在 3.12 版被加入.
- threading.gettrace()¶
Get the trace function as set by
settrace().在 3.10 版被加入.
- threading.setprofile(func)¶
Set a profile function for all threads started from the
threadingmodule. The func will be passed tosys.setprofile()for each thread, before itsrun()method is called.
- threading.setprofile_all_threads(func)¶
Set a profile function for all threads started from the
threadingmodule and all Python threads that are currently executing.The func will be passed to
sys.setprofile()for each thread, before itsrun()method is called.在 3.12 版被加入.
- threading.getprofile()¶
取得由
setprofile()設定的剖析函式。在 3.10 版被加入.
- threading.stack_size([size])¶
Return the thread stack size used when creating new threads. The optional size argument specifies the stack size to be used for subsequently created threads, and must be 0 (use platform or configured default) or a positive integer value of at least 32,768 (32 KiB). If size is not specified, 0 is used. If changing the thread stack size is unsupported, a
RuntimeErroris raised. If the specified stack size is invalid, aValueErroris raised and the stack size is unmodified. 32 KiB is currently the minimum supported stack size value to guarantee sufficient stack space for the interpreter itself. Note that some platforms may have particular restrictions on values for the stack size, such as requiring a minimum stack size > 32 KiB or requiring allocation in multiples of the system memory page size - platform documentation should be referred to for more information (4 KiB pages are common; using multiples of 4096 for the stack size is the suggested approach in the absence of more specific information).可用性: Windows, pthreads.
Unix platforms with POSIX threads support.
此模組也定義了以下常數:
- threading.TIMEOUT_MAX¶
The maximum value allowed for the timeout parameter of blocking functions (
Lock.acquire(),RLock.acquire(),Condition.wait(), etc.). Specifying a timeout greater than this value will raise anOverflowError.在 3.2 版被加入.
This module defines a number of classes, which are detailed in the sections below.
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 of the methods described below are executed atomically.
Thread-local data¶
Thread-local data is data whose values are thread specific. If you
have data that you want to be local to a thread, create a
local object and use its attributes:
>>> mydata = local()
>>> mydata.number = 42
>>> mydata.number
42
You can also access the local-object's dictionary:
>>> mydata.__dict__
{'number': 42}
>>> mydata.__dict__.setdefault('widgets', [])
[]
>>> mydata.widgets
[]
If we access the data in a different thread:
>>> log = []
>>> def f():
... items = sorted(mydata.__dict__.items())
... log.append(items)
... mydata.number = 11
... log.append(mydata.number)
>>> import threading
>>> thread = threading.Thread(target=f)
>>> thread.start()
>>> thread.join()
>>> log
[[], 11]
we get different data. Furthermore, changes made in the other thread don't affect data seen in this thread:
>>> mydata.number
42
Of course, values you get from a local object, including their
__dict__ attribute, are for whatever thread was current
at the time the attribute was read. For that reason, you generally
don't want to save these values across threads, as they apply only to
the thread they came from.
You can create custom local objects by subclassing the
local class:
>>> class MyLocal(local):
... number = 2
...