threading — Thread-based parallelism

소스 코드: Lib/threading.py


This module constructs higher-level threading interfaces on top of the lower level _thread module.

버전 3.7에서 변경: 이 모듈은 선택 사양이었지만, 이제는 항상 사용 가능합니다.

더 보기

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 구현 상세: CPython에서는, 전역 인터프리터 록으로 인해 한 번에 하나의 스레드만 파이썬 코드를 실행할 수 있습니다 (설사 일부 성능 지향 라이브러리가 이 제한을 극복할 수 있을지라도). 응용 프로그램에서 멀티 코어 기계의 계산 자원을 더 잘 활용하려면 multiprocessing이나 concurrent.futures.ProcessPoolExecutor를 사용하는 것이 좋습니다. 그러나, 여러 I/O 병목 작업을 동시에 실행하고 싶을 때 threading은 여전히 적절한 모델입니다.

Availability: not Emscripten, not WASI.

This module does not work or is not available on WebAssembly platforms wasm32-emscripten and wasm32-wasi. See WebAssembly platforms for more information.

이 모듈은 다음 함수를 정의합니다:

threading.active_count()

현재 살아있는 Thread 객체 수를 반환합니다. 반환된 수는 enumerate()가 반환한 리스트의 길이와 같습니다.

The function activeCount is a deprecated alias for this function.

threading.current_thread()

호출자의 제어 스레드에 해당하는 현재 Thread 객체를 반환합니다. 호출자의 제어 스레드가 threading 모듈을 통해 만들어지지 않았으면, 기능이 제한된 더미 스레드 객체가 반환됩니다.

The function currentThread is a deprecated alias for this function.

threading.excepthook(args, /)

Thread.run()에 의해 발생한 포착되지 않은 예외를 처리합니다.

args 인자에는 다음과 같은 어트리뷰트가 있습니다:

  • exc_type: 예외 형.

  • exc_value: 예외 값, None일 수 있습니다.

  • exc_traceback: 예외 트레이스백, None일 수 있습니다.

  • thread: 예외를 발생시킨 스레드, None일 수 있습니다.

exc_typeSystemExit이면, 예외는 조용히 무시됩니다. 그렇지 않으면, sys.stderr에 예외가 인쇄됩니다.

이 함수에서 예외가 발생하면, 이를 처리하기 위해 sys.excepthook()이 호출됩니다.

Thread.run()에 의해 발생한 포착되지 않은 예외를 처리하는 방법을 제어하기 위해 threading.excepthook()을 재정의할 수 있습니다.

사용자 정의 훅을 사용하여 exc_value를 저장하면 참조 순환을 만들 수 있습니다. 예외가 더는 필요하지 않을 때 참조 순환을 끊기 위해 명시적으로 지워야 합니다.

사용자 정의 훅을 사용하여 thread를 저장하면 파이널라이즈 중인 객체로 설정되면 이를 되살릴 수 있습니다. 객체를 되살리는 것을 방지하려면 사용자 정의 훅이 완료된 후 thread를 보관하지 마십시오.

더 보기

sys.excepthook()은 포착되지 않은 예외를 처리합니다.

Added in version 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.

Added in version 3.10.

threading.get_ident()

현재 스레드의 ‘스레드 식별자’를 반환합니다. 이것은 0이 아닌 정수입니다. 이 값은 직접적인 의미가 없습니다; 이것은 매직 쿠키로 사용하려는 것입니다, 예를 들어 스레드 특정 데이터의 딕셔너리를 인덱싱하는 데 사용됩니다. 스레드 식별자는 스레드가 종료되고 다른 스레드가 만들어질 때 재활용될 수 있습니다.

Added in version 3.3.

threading.get_native_id()

커널이 할당한 현재 스레드의 네이티브 정수 스레드 ID를 반환합니다. 음수가 아닌 정수입니다. 이 값은 시스템 전체에서 이 특정 스레드를 고유하게 식별하는 데 사용될 수 있습니다 (스레드가 종료될 때까지, 그 후에는 OS에서 값을 재활용할 수 있습니다).

Availability: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD.

Added in version 3.8.

threading.enumerate()

Return a list of all Thread objects currently active. The list includes daemonic threads and dummy thread objects created by current_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()

메인 Thread 객체를 반환합니다. 정상적인 조건에서, 메인 스레드는 파이썬 인터프리터가 시작된 스레드입니다.

Added in version 3.4.

threading.settrace(func)

threading 모듈에서 시작된 모든 스레드에 대한 추적 함수를 설정합니다. funcrun() 메서드가 호출되기 전에 각 스레드에 대해 sys.settrace()로 전달됩니다.

threading.settrace_all_threads(func)

Set a trace function for all threads started from the threading module and all Python threads that are currently executing.

The func will be passed to sys.settrace() for each thread, before its run() method is called.

Added in version 3.12.

threading.gettrace()

Get the trace function as set by settrace().

Added in version 3.10.

threading.setprofile(func)

threading 모듈에서 시작된 모든 스레드에 대한 프로파일 함수를 설정합니다. funcrun() 메서드가 호출되기 전에 각 스레드에 대해 sys.setprofile()로 전달됩니다.

threading.setprofile_all_threads(func)

Set a profile function for all threads started from the threading module and all Python threads that are currently executing.

The func will be passed to sys.setprofile() for each thread, before its run() method is called.

Added in version 3.12.

threading.getprofile()

Get the profiler function as set by setprofile().

Added in version 3.10.

threading.stack_size([size])

새 스레드를 만들 때 사용된 스레드 스택 크기를 반환합니다. 선택적 size 인자는 이후에 만들어지는 스레드에 사용할 스택 크기를 지정하며, 0(플랫폼이나 구성된 기본값을 사용합니다)이거나 32,768 (32 KiB) 이상의 양의 정숫값이어야 합니다. size를 지정하지 않으면, 0이 사용됩니다. 스레드 스택 크기 변경이 지원되지 않으면, RuntimeError가 발생합니다. 지정된 스택 크기가 유효하지 않으면, ValueError가 발생하고 스택 크기는 수정되지 않습니다. 32 KiB는 현재 인터프리터 자체에 충분한 스택 공간을 보장하기 위해 지원되는 최소 스택 크기 값입니다. 최소 스택 크기가 32 KiB 보다 커야 한다거나 시스템 메모리 페이지 크기의 배수로 할당해야 하는 등 일부 플랫폼에는 스택 크기 값에 대한 특정 제한이 있을 수 있습니다 - 자세한 내용은 플랫폼 설명서를 참조하십시오 (4 KiB 페이지는 흔합니다; 스택 크기에 4096의 배수를 사용하는 것이 더 구체적인 정보가 없을 때 제안하는 방법입니다).

Availability: Windows, pthreads.

Unix platforms with POSIX threads support.

이 모듈은 또한 다음 상수를 정의합니다:

threading.TIMEOUT_MAX

블로킹 함수(Lock.acquire(), RLock.acquire(), Condition.wait() 등)의 timeout 매개 변수에 허용되는 최댓값. 이 값보다 큰 timeout을 지정하면 OverflowError가 발생합니다.

Added in version 3.2.

이 모듈은 아래 섹션에 자세히 설명되는 많은 클래스를 정의합니다.

이 모듈의 설계는 Java의 스레딩 모델에 약하게 기반합니다. 그러나, Java가 록(locks)과 조건 변수(condition variables)를 모든 객체의 기본 동작으로 만들지만, 파이썬에서는 별도의 객체입니다. 파이썬의 Thread 클래스는 Java Thread 클래스 동작의 부분 집합을 지원합니다; 현재, 우선순위가 없고, 스레드 그룹이 없으며 스레드를 파괴, 중지, 일시 중지, 재개 또는 인터럽트 할 수 없습니다. 구현될 때, Java 스레드 클래스의 정적 메서드는 모듈 수준 함수에 매핑됩니다.

아래에 설명된 모든 메서드는 원자 적으로 실행됩니다.

스레드 로컬 데이터

스레드 로컬 데이터는 값이 스레드에만 한정되는 데이터입니다. 스레드 로컬 데이터를 관리하려면, local(또는 서브 클래스) 인스턴스를 만들고 그것에 어트리뷰트를 저장하십시오:

mydata = threading.local()
mydata.x = 1

인스턴스 값은 개별 스레드마다 다릅니다.

class threading.local

스레드 로컬 데이터를 나타내는 클래스.

For more details and extensive examples, see the documentation string of the _threading_local module: Lib/_threading_local.py.

Thread 객체

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() 메서드를 호출합니다.

일단 스레드의 활동이 시작되면, 스레드는 ‘살아있는(alive)’ 것으로 간주합니다. run() 메서드가 정상적으로 혹은 처리되지 않은 예외를 발생시켜서 종료할 때 살아있음을 멈춥니다. is_alive() 메서드는 스레드가 살아있는지 검사합니다.

다른 스레드는 스레드의 join() 메서드를 호출할 수 있습니다. 이것은 join() 메서드가 호출된 스레드가 종료될 때까지 호출하는 스레드를 블록 합니다.

스레드에는 이름이 있습니다. 이름은 생성자에 전달되고, name 어트리뷰트를 통해 읽거나 변경할 수 있습니다.

run() 메서드에서 예외가 발생하면, 이를 처리하기 위해 threading.excepthook()이 호출됩니다. 기본적으로, threading.excepthook()SystemExit를 조용히 무시합니다.

스레드는 “데몬 스레드”로 플래그 할 수 있습니다. 이 플래그의 의미는 오직 데몬 스레드만 남았을 때 전체 파이썬 프로그램이 종료된다는 것입니다. 초깃값은 만드는 스레드에서 상속됩니다. 플래그는 daemon 프로퍼티나 daemon 생성자 인자를 통해 설정할 수 있습니다.

참고

종료 시 데몬 스레드는 갑자기 중지됩니다. 그들의 자원(가령 열린 파일, 데이터베이스 트랜잭션 등)은 제대로 해제되지 않을 수 있습니다. 스레드가 우아하게 중지되도록 하려면, 스레드를 데몬이 아니도록 만들고 Event와 같은 적절한 신호 메커니즘을 사용하십시오.

“메인 스레드” 객체가 있습니다; 이것은 파이썬 프로그램의 초기 제어 스레드에 해당합니다. 이것은 데몬 스레드가 아닙니다.

There is the possibility that “dummy thread objects” are created. These are thread objects corresponding to “alien threads”, which are threads of control started outside the threading module, such as directly from C code. Dummy thread objects have limited functionality; they are always considered alive and daemonic, and cannot be joined. They are never deleted, since it is impossible to detect the termination of alien threads.

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

이 생성자는 항상 키워드 인자로 호출해야 합니다. 인자는 다음과 같습니다:

group should be None; reserved for future extension when a ThreadGroup class is implemented.

targetrun() 메서드에 의해 호출될 콜러블 객체입니다. 기본값은 None이며, 아무것도 호출되지 않습니다.

name is the thread name. By default, a unique name is constructed of the form “Thread-N” where N is a small decimal number, or “Thread-N (target)” where “target” is target.__name__ if the target argument is specified.

args is a list or tuple of arguments for the target invocation. Defaults to ().

kwargs는 target 호출을 위한 키워드 인자의 딕셔너리입니다. 기본값은 {}입니다.

None이 아니면, daemon은 스레드가 데몬인지를 명시적으로 설정합니다. None(기본값)이면, 데몬 속성은 현재 스레드에서 상속됩니다.

서브 클래스가 생성자를 재정의하면, 스레드에 다른 작업을 수행하기 전에 베이스 클래스 생성자(Thread.__init__())를 호출해야 합니다.

버전 3.3에서 변경: Added the daemon parameter.

버전 3.10에서 변경: Use the target name if name argument is omitted.

start()

스레드 활동을 시작합니다.

스레드 객체 당 최대 한 번 호출되어야 합니다. 객체의 run() 메서드가 별도의 제어 스레드에서 호출되도록 배치합니다.

이 메서드는 같은 스레드 객체에서 두 번 이상 호출되면, RuntimeError를 발생시킵니다.

run()

스레드의 활동을 표현하는 메서드.

서브 클래스에서 이 메서드를 재정의할 수 있습니다. 표준 run() 메서드는 target 인자로 객체의 생성자에 전달된 콜러블 객체를 호출합니다, 있다면 argskwargs 인자에서 각각 취한 위치와 키워드 인자로 호출합니다.

Using list or tuple as the args argument which passed to the Thread could achieve the same effect.

Example:

>>> from threading import Thread
>>> t = Thread(target=print, args=[1])
>>> t.run()
1
>>> t = Thread(target=print, args=(1,))
>>> t.run()
1
join(timeout=None)

스레드가 종료할 때까지 기다립니다. join() 메서드가 호출된 스레드가 정상적으로 혹은 처리되지 않은 예외를 통해 종료하거나 선택적 시간제한 초과가 발생할 때까지 호출하는 스레드를 블록 합니다.

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). As join() always returns None, you must call is_alive() after join() to decide whether a timeout happened – if the thread is still alive, the join() call timed out.

timeout 인자가 없거나 None이면, 스레드가 종료될 때까지 작업이 블록 됩니다.

A thread can be joined many times.

교착 상태를 유발할 수 있어서 현재 스레드를 조인하려고 시도하면 join()RuntimeError를 발생시킵니다. 스레드가 시작되기 전에 join() 하는 것도 에러이고 같은 예외가 발생합니다.

name

식별 목적으로만 사용되는 문자열. 의미는 없습니다. 여러 스레드에 같은 이름을 지정할 수 있습니다. 초기 이름은 생성자가 설정합니다.

getName()
setName()

Deprecated getter/setter API for name; use it directly as a property instead.

버전 3.10부터 폐지됨.

ident

이 스레드의 ‘스레드 식별자’ 또는 스레드가 시작되지 않았으면 None. 이것은 0이 아닌 정수입니다. get_ident() 함수를 참조하십시오. 스레드 식별자는 스레드가 종료되고 다른 스레드가 만들어질 때 재활용될 수 있습니다. 스레드가 종료된 후에도 식별자를 사용할 수 있습니다.

native_id

The Thread ID (TID) of this thread, as assigned by the OS (kernel). This is a non-negative integer, or None if the thread has not been started. See the get_native_id() function. This 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).

참고

프로세스 ID 와 유사하게, 스레드 ID는 스레드가 만들어진 시점부터 스레드가 종료될 때까지만 유효(시스템 전체에서 고유함이 보장)합니다.

Availability: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD.

Added in version 3.8.

is_alive()

스레드가 살아있는지를 반환합니다.

이 메서드는 run() 메서드가 시작되기 직전부터 run() 메서드가 종료된 직후까지 True를 반환합니다. 모듈 함수 enumerate()는 모든 살아있는 스레드 리스트를 반환합니다.

daemon

A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called, otherwise RuntimeError 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 to daemon = False.

살아있는 데몬이 아닌 스레드가 남아 있지 않으면 전체 파이썬 프로그램이 종료됩니다.

isDaemon()
setDaemon()

Deprecated getter/setter API for daemon; use it directly as a property instead.

버전 3.10부터 폐지됨.

Lock 객체

프리미티브 록(primitive lock)은 잠겨있을 때 특정 스레드가 소유하지 않는 동기화 프리미티브입니다. 파이썬에서는 현재 _thread 확장 모듈에 의해 직접 구현되는 가장 낮은 수준의 동기화 프리미티브입니다.

프리미티브 록은 두 상태 중 하나입니다, “잠금(locked)”이나 “잠금 해제(unlocked)”. 잠금 해제 상태로 만들어집니다. 두 가지 기본 메서드가 있습니다, acquire()release(). 상태가 잠금 해제일 때, acquire()는 상태를 잠금으로 변경하고 즉시 반환합니다. 상태가 잠금일 때, acquire()는 다른 스레드에서의 release()에 호출이 잠금 해제로 변경할 때까지 블록 된 후, acquire() 호출이 이를 잠금으로 재설정하고 반환합니다. release() 메서드는 잠금 상태에서만 호출해야 합니다; 상태를 잠금 해제로 변경하고 즉시 반환합니다. 잠금 해제된 록을 해제하려고 하면, RuntimeError가 발생합니다.

록은 컨텍스트 관리자 프로토콜도 지원합니다.

둘 이상의 스레드가 acquire()에서 블록 되어 상태가 잠금 해제가 되기를 기다릴 때, release() 호출이 상태를 잠금 해제로 재설정하면 하나의 스레드만 진행됩니다; 대기 중인 스레드 중 어느 것이 진행하는지는 정의되지 않았으며, 구현에 따라 다를 수 있습니다.

모든 메서드는 원자 적으로 실행됩니다.

class threading.Lock

프리미티브 록 객체를 구현하는 클래스. 일단 스레드가 록을 획득하면, 이후에 해당 록을 확보하려고 시도하면 해제될 때까지 블록 합니다; 모든 스레드가 해제할 수 있습니다.

Lock은 실제로는 플랫폼에서 지원하는 가장 효율적인 버전의 구상 Lock 클래스 인스턴스를 반환하는 팩토리 함수임에 유의하십시오.

acquire(blocking=True, timeout=-1)

블로킹이거나 비 블로킹으로, 록을 획득합니다.

blocking 인자를 True(기본값)로 설정하여 호출하면, 록이 잠금 해제될 때까지 블록 한 다음, 잠금으로 설정하고 True를 반환합니다.

blocking 인자를 False로 설정하여 호출하면, 블록 하지 않습니다. blockingTrue로 설정된 호출이 블록 될 것이라면, 즉시 False를 반환합니다; 그렇지 않으면, 록을 잠금으로 설정하고 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. A timeout argument of -1 specifies an unbounded wait. It is forbidden to specify a timeout when blocking is False.

록이 성공적으로 획득되면 반환 값은 True이고, 그렇지 않으면 (예를 들어 timeout이 만료되면) False입니다.

버전 3.2에서 변경: timeout 매개 변수가 추가되었습니다.

버전 3.2에서 변경: 하부 스레딩 구현이 지원한다면 POSIX에서 시그널로 록 획득을 중단할 수 있습니다.

release()

록을 해제합니다. 록을 획득한 스레드뿐만 아니라 모든 스레드에서 호출할 수 있습니다.

록이 잠금일 때, 잠금 해제로 재설정하고 반환합니다. 록이 잠금 해제될 때까지 다른 스레드가 블록 되어 기다리고 있으면, 그들 중 정확히 하나의 스레드가 진행되도록 합니다.

잠금 해제된 록에서 호출되면, RuntimeError가 발생합니다.

반환 값이 없습니다.

locked()

Return True if the lock is acquired.

RLock 객체

재진입 록(reentrant lock)은 같은 스레드에 의해 여러 번 획득될 수 있는 동기화 프리미티브입니다. 내부적으로, 프리미티브 록에서 사용하는 잠금/잠금 해제 상태에 더해 “소유하는 스레드(owning thread)”와 “재귀 수준(recursion level)” 개념을 사용합니다. 잠금 상태에서는, 어떤 스레드가 록을 소유합니다; 잠금 해제 상태에서는 아무런 스레드도 록을 소유하지 않습니다.

Threads call a lock’s acquire() method to lock it, and its release() method to unlock it.

참고

Reentrant locks support the context management protocol, so it is recommended to use with instead of manually calling acquire() and release() to handle acquiring and releasing the lock for a block of code.

RLock’s acquire()/release() call pairs may be nested, unlike Lock’s acquire()/release(). Only the final release() (the release() of the outermost pair) resets the lock to an unlocked state and allows another thread blocked in acquire() to proceed.

acquire()/release() must be used in pairs: each acquire must have a release in the thread that has acquired the lock. Failing to call release as many times the lock has been acquired can lead to deadlock.

class threading.RLock

이 클래스는 재진입 록 객체를 구현합니다. 재진입 록은 획득한 스레드에서 해제해야 합니다. 일단 스레드가 재진입 록을 획득하면, 같은 스레드는 블록 하지 않고 다시 스레드를 획득할 수 있습니다; 스레드는 획득할 때마다 한 번씩 해제해야 합니다.

RLock은 실제로는 플랫폼에서 지원하는 가장 효율적인 버전의 구상 RLock 클래스 인스턴스를 반환하는 팩토리 함수임에 유의하십시오.

acquire(blocking=True, timeout=-1)

블로킹이거나 비 블로킹으로, 록을 획득합니다.

더 보기

Using RLock as a context manager

Recommended over manual acquire() and release() calls whenever practical.

When invoked with the blocking argument set to True (the default):

  • If no thread owns the lock, acquire the lock and return immediately.

  • If another thread owns the lock, block until we are able to acquire lock, or timeout, if set to a positive float value.

  • If the same thread owns the lock, acquire the lock again, and return immediately. This is the difference between Lock and RLock; Lock handles this case the same as the previous, blocking until the lock can be acquired.

When invoked with the blocking argument set to False:

  • If no thread owns the lock, acquire the lock and return immediately.

  • If another thread owns the lock, return immediately.

  • If the same thread owns the lock, acquire the lock again and return immediately.

In all cases, if the thread was able to acquire the lock, return True. If the thread was unable to acquire the lock (i.e. if not blocking or the timeout was reached) return False.

If called multiple times, failing to call release() as many times may lead to deadlock. Consider using RLock as a context manager rather than calling acquire/release directly.

버전 3.2에서 변경: timeout 매개 변수가 추가되었습니다.

release()

재귀 수준을 낮추면서, 잠금을 해제합니다. 감소 후에 0이 되면, 록을 잠금 해제로 (아무런 스레드도 소유하지 않은) 재설정하고, 록이 잠금 해제되도록 기다리면서 블록 된 다른 스레드가 있으면, 그중 정확히 하나가 진행되도록 합니다. 감소 후에 재귀 수준이 여전히 0이 아니면, 록은 잠금이고, 호출하는 스레드에 의해 소유된 채로 유지됩니다.

Only call this method when the calling thread owns the lock. A RuntimeError is raised if this method is called when the lock is not acquired.

반환 값이 없습니다.

Condition 객체

조건 변수(condition variable)는 항상 어떤 종류의 록과 연관됩니다; 이것은 전달되거나 기본적으로 만들어집니다. 전달하는 것은 여러 조건 변수가 같은 록을 공유해야 할 때 유용합니다. 록은 조건 객체의 일부입니다: 별도로 추적할 필요가 없습니다.

조건 변수는 컨텍스트 관리자 프로토콜을 준수합니다: with 문을 사용해서 감싼 블록의 지속 시간 동안 연관된 록을 획득합니다. acquire()release() 메서드도 연관된 록의 해당 메서드를 호출합니다.

다른 메서드들은 연관된 록을 잡은 상태에서 호출해야 합니다. wait() 메서드는 록을 해제한 다음, 다른 스레드가 notify()notify_all()을 호출하여 록을 해제할 때까지 블록 합니다. 일단 깨어나면, wait()는 록을 다시 획득하고 반환합니다. 시간제한을 지정할 수도 있습니다.

notify() 메서드는 있다면 조건 변수를 기다리는 스레드 중 하나를 깨웁니다. notify_all() 메서드는 조건 변수를 기다리는 모든 스레드를 깨웁니다.

참고: notify()notify_all() 메서드는 록을 해제하지 않습니다; 이것은 깨어난 스레드나 스레드들이 wait() 호출에서 즉시 반환되지 않지만, notify()notify_all()을 호출한 스레드가 최종적으로 록 소유권을 포기할 때만 반환됨을 의미합니다.

조건 변수를 사용하는 일반적인 프로그래밍 스타일은 록을 사용하여 어떤 공유 상태에 대한 액세스를 동기화합니다; 특정 상태 변경에 관심 있는 스레드는 원하는 상태를 볼 때까지 wait()를 반복적으로 호출하는 반면, 상태를 변경하는 스레드는 대기자 중 하나가 원하는 상태일 수 있도록 상태를 변경할 때 notify()notify_all()을 호출합니다. 예를 들어, 다음 코드는 무제한 버퍼 용량의 일반적인 생산자-소비자 상황입니다:

# 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()

wait()가 임의의 긴 시간 후에 반환될 수 있고, notify() 호출을 유발한 조건이 더는 참이 아닐 수 있기 때문에, 응용 프로그램의 조건에 대한 while 루프 검사가 필요합니다. 이것은 다중 스레드 프로그래밍에 본질적으로 수반됩니다. wait_for() 메서드를 사용하면 조건 검사를 자동화하고 시간제한 계산을 쉽게 수행할 수 있습니다:

# Consume an item
with cv:
    cv.wait_for(an_item_is_available)
    get_an_available_item()

notify()notify_all() 중에서 선택하려면, 하나의 상태 변경에 흥미 있는 대기 중인 스레드가 하나일지 여러 개일지를 고려하십시오. 예를 들어 일반적인 생산자-소비자 상황에서, 하나의 항목을 버퍼에 추가하면 오직 하나의 소비자 스레드만 깨울 필요가 있습니다.

class threading.Condition(lock=None)

이 클래스는 조건 변수 객체를 구현합니다. 조건 변수를 사용하면 하나 이상의 스레드가 다른 스레드에 의해 통지될 때까지 기다릴 수 있습니다.

lock 인자가 제공되고 None이 아니면, Lock이나 RLock 객체여야 하며, 하부 록으로 사용됩니다. 그렇지 않으면, 새 RLock 객체가 만들어지고 하부 록으로 사용됩니다.

버전 3.3에서 변경: 팩토리 함수에서 클래스로 변경되었습니다.

acquire(*args)

하부 록을 획득합니다. 이 메서드는 하부 록에서 해당 메서드를 호출합니다; 반환 값은 그 메서드가 반환하는 것입니다.

release()

하부 록을 해제합니다. 이 메서드는 하부 록에서 해당 메서드를 호출합니다; 반환 값이 없습니다.

wait(timeout=None)

통지되거나 시간제한이 만료될 때까지 기다립니다. 이 메서드가 호출될 때 호출하는 스레드가 록을 획득하지 않았으면, RuntimeError가 발생합니다.

이 메서드는 하부 록을 해제한 다음, 같은 조건 변수에 대한 다른 스레드에서의 notify()notify_all() 호출에 의해 깨어날 때까지 또는 선택적 시간제한 만료가 발생할 때까지 블록 합니다. 일단 깨어나거나 시간제한이 만료되면, 록을 다시 획득하고 반환합니다.

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).

하부 록이 RLock일 때, 록이 여러 번 재귀적으로 획득되었을 때 록을 실제로 잠금 해제하지 못할 수 있기 때문에, release() 메서드를 사용하여 록을 해제하지 않습니다. 대신, RLock 클래스의 내부 인터페이스가 사용되어, 재귀적으로 여러 번 획득한 경우에도 실제로 록을 잠금 해제합니다. 그런 다음 다른 내부 인터페이스를 사용하여 록을 다시 획득할 때 재귀 수준을 복원합니다.

주어진 timeout이 만료되지 않는 한 반환 값은 True이며, 만료되면 False입니다.

버전 3.2에서 변경: 이전에는, 메서드가 항상 None을 반환했습니다.

wait_for(predicate, timeout=None)

조건이 참으로 평가될 때까지 기다립니다. predicate는 불리언 값으로 해석될 결과를 반환하는 콜러블 이어야 합니다. 최대 대기 시간을 주는 timeout이 제공될 수 있습니다.

이 유틸리티 메서드는 술어(predicate)가 충족될 때까지, 또는 시간제한 만료가 발생할 때까지 wait()를 반복적으로 호출할 수 있습니다. 반환 값은 predicate의 마지막 반환 값이며 메서드가 시간제한 만료되면 False로 평가됩니다.

시간제한 기능을 무시할 때, 이 메서드를 호출하는 것은 대략 다음과 같이 작성하는 것과 동등합니다:

while not predicate():
    cv.wait()

따라서, wait()와 같은 규칙이 적용됩니다: 호출될 때 록을 잡고 있어야 하며 반환할 때 다시 확보됩니다. predicate는 록을 잡고 있는 상태로 평가됩니다.

Added in version 3.2.

notify(n=1)

기본적으로, (있다면) 이 조건에서 대기 중인 하나의 스레드를 깨웁니다. 이 메서드가 호출될 때 호출하는 스레드가 잠금을 획득하지 않았으면 RuntimeError가 발생합니다.

이 메서드는 조건 변수를 기다리는 스레드를 최대 n 개 깨웁니다; 기다리는 스레드가 없으면 아무런 일도 하지 않습니다.

적어도 n 스레드가 대기 중이면, 현재 구현은 정확히 n 스레드를 깨웁니다. 그러나, 이 동작에 의존하는 것은 안전하지 않습니다. 미래에는, 최적화된 구현이 때때로 n 스레드보다 많이 깨울 수 있습니다.

참고: 깨어난 스레드는 록을 다시 획득할 때까지 wait() 호출에서 실제로 반환하지 않습니다. notify()가 록을 해제하지 않기 때문에, 호출자가 해제해야 합니다.

notify_all()

이 조건에서 대기 중인 모든 스레드를 깨웁니다. 이 메서드는 notify()처럼 작동하지만, 하나 대신에 대기 중인 모든 스레드를 깨웁니다. 이 메서드가 호출될 때 호출하는 스레드가 잠금을 획득하지 않았으면 RuntimeError가 발생합니다.

The method notifyAll is a deprecated alias for this method.

Semaphore 객체

이것은 일찌감치 네덜란드 컴퓨터 과학자 Edsger W. Dijkstra가 발명한, 컴퓨터 과학 역사상 가장 오래된 동기화 프리미티브 중 하나입니다 (그는 acquire()release() 대신 P()V()라는 이름을 사용했습니다).

세마포어는 각 acquire() 호출에 의해 감소하고 각 release() 호출에 의해 증가하는 내부 카운터를 관리합니다. 카운터는 절대 0 밑으로 떨어질 수 없습니다; acquire()가 0임을 발견하면, 다른 스레드가 release()를 호출할 때까지 대기하면서 블록 합니다.

세마포어도 컨텍스트 관리자 프로토콜을 지원합니다.

class threading.Semaphore(value=1)

이 클래스는 세마포어 객체를 구현합니다. 세마포어는 release() 호출 수에서 acquire() 호출 수를 빼고, 초깃값을 더한 원자 적 카운터를 관리합니다. acquire() 메서드는 카운터를 음수로 만들지 않고 반환할 수 있을 때까지 필요하면 블록 합니다. 지정하지 않으면, value의 기본값은 1입니다.

선택적 인자는 내부 카운터의 초깃 값(value)을 제공합니다; 기본값은 1입니다. 주어진 value가 0보다 작으면 ValueError가 발생합니다.

버전 3.3에서 변경: 팩토리 함수에서 클래스로 변경되었습니다.

acquire(blocking=True, timeout=None)

세마포어를 획득합니다.

인자 없이 호출될 때:

  • 진입 시 내부 카운터가 0보다 크면, 1 감소시키고 즉시 True를 반환합니다.

  • 진입 시 내부 카운터가 0이면, release()를 호출하여 깨울 때까지 블록 합니다. 일단 깨어나면 (그리고 카운터가 0보다 크면), 카운터를 1줄이고 True를 반환합니다. release()를 호출할 때마다 정확히 하나의 스레드가 깨어납니다. 스레드가 깨어나는 순서에 의존해서는 안 됩니다.

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.

None 이외의 timeout으로 호출하면, 최대 timeout 초 동안 블록 합니다. 그 기간 획득이 완료되지 않으면, False를 반환합니다. 그렇지 않으면 True를 반환합니다.

버전 3.2에서 변경: timeout 매개 변수가 추가되었습니다.

release(n=1)

내부 카운터를 n 증가시키면서 세마포어를 해제합니다. 진입 시 0이고 다른 스레드가 다시 0보다 커지기를 기다리고 있으면, 해당 스레드를 n개 깨웁니다.

버전 3.9에서 변경: 여러 대기 스레드를 한 번에 해제하기 위해 n 매개 변수를 추가했습니다.

class threading.BoundedSemaphore(value=1)

경계 세마포어 객체를 구현하는 클래스. 경계 세마포어는 현재 값이 초깃값을 초과하지 않는지 확인합니다. 그렇다면, ValueError가 발생합니다. 대부분은 세마포어는 제한된 용량의 자원을 보호하는 데 사용됩니다. 세마포어가 너무 여러 번 해제되면 버그의 징조입니다. 지정하지 않으면, value의 기본값은 1입니다.

버전 3.3에서 변경: 팩토리 함수에서 클래스로 변경되었습니다.

Semaphore

세마포어는 예를 들어 데이터베이스 서버와 같이 제한된 용량의 자원을 보호하는 데 종종 사용됩니다. 자원의 크기가 고정된 상황에서는, 경계 세마포어를 사용해야 합니다. 작업자 스레드를 만들기 전에, 메인 스레드가 세마포어를 초기화합니다:

maxconnections = 5
# ...
pool_sema = BoundedSemaphore(value=maxconnections)

일단 만들어지면, 작업자 스레드는 서버에 연결해야 할 때 세마포어의 acquire 및 release 메서드를 호출합니다:

with pool_sema:
    conn = connectdb()
    try:
        # ... use connection ...
    finally:
        conn.close()

경계 세마포어를 사용하면 세마포어가 획득한 것보다 더 많이 해제되는 프로그래밍 에러가 감지되지 않을 가능성이 줄어듭니다.

Event 객체

이것은 스레드 간 통신을 위한 가장 간단한 메커니즘 중 하나입니다: 하나의 스레드는 이벤트를 알리고 다른 스레드는 이를 기다립니다.

이벤트 객체는 set() 메서드를 사용하여 참으로 설정하고 clear() 메서드를 사용하여 거짓으로 재설정 할 수 있는 내부 플래그를 관리합니다. wait() 메서드는 플래그가 참이 될 때까지 블록 합니다.

class threading.Event

이벤트 객체를 구현하는 클래스. 이벤트는 set() 메서드로 참으로 설정하고 clear() 메서드로 거짓으로 재설정 할 수 있는 플래그를 관리합니다. wait() 메서드는 플래그가 참이 될 때까지 블록 합니다. 플래그는 처음에는 거짓입니다.

버전 3.3에서 변경: 팩토리 함수에서 클래스로 변경되었습니다.

is_set()

내부 플래그가 참이면 그리고 오직 그때만 True를 반환합니다.

The method isSet is a deprecated alias for this method.

set()

내부 플래그를 참으로 설정합니다. 이것이 참이 되기를 기다리는 모든 스레드가 깨어납니다. 일단 플래그가 참이면 wait()를 호출하는 스레드는 전혀 블록 하지 않습니다.

clear()

내부 플래그를 거짓으로 재설정합니다. 이후 wait()를 호출하는 스레드는 내부 플래그를 다시 참으로 설정하기 위해 set()을 호출할 때까지 블록 합니다.

wait(timeout=None)

Block as long as the internal flag is false and the timeout, if given, has not expired. The return value represents the reason that this blocking method returned; True if returning because the internal flag is set to true, or False if a timeout is given and the internal flag did not become true within the given wait time.

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.

버전 3.1에서 변경: 이전에는, 메서드가 항상 None을 반환했습니다.

Timer 객체

이 클래스는 특정 시간이 지난 후에만 실행되어야 하는 조치를 나타냅니다 – 타이머. TimerThread의 서브 클래스이며 사용자 정의 스레드를 만드는 예제로도 기능합니다.

Timers are started, as with threads, by calling their Timer.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)

interval 초가 지난 후 args 인자와 kwargs 키워드 인자로 function을 실행하는 타이머를 만듭니다. argsNone(기본값)이면 빈 리스트가 사용됩니다. kwargsNone(기본값)이면 빈 딕셔너리가 사용됩니다.

버전 3.3에서 변경: 팩토리 함수에서 클래스로 변경되었습니다.

cancel()

타이머를 중지하고, 타이머 조치의 실행을 취소합니다. 타이머가 아직 대기 상태에 있을 때만 작동합니다.

Barrier 객체

Added in version 3.2.

이 클래스는 서로를 기다려야 하는 고정된 수의 스레드에서 사용할 수 있는 간단한 동기화 프리미티브를 제공합니다. 각 스레드는 wait() 메서드를 호출하여 장벽(barrier)을 통과하려고 시도하고 모든 스레드가 wait() 호출을 수행할 때까지 블록 합니다. 이 시점에서, 스레드가 동시에 해제됩니다.

장벽은 같은 수의 스레드에 대해 여러 번 재사용 할 수 있습니다.

예를 들어, 다음은 클라이언트와 서버 스레드를 동기화하는 간단한 방법입니다:

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)

parties 수의 스레드에 대한 장벽 객체를 만듭니다. 제공되면, action은 해제될 때 스레드 중 하나가 호출할 콜러블입니다. timeoutwait() 메서드에 대해 지정되지 않을 때 사용될 기본 시간제한 값입니다.

wait(timeout=None)

장벽을 통과합니다. 장벽에 속한 모든 스레드가 이 함수를 호출할 때, 모두 동시에 해제됩니다. timeout이 제공되면, 클래스 생성자에 제공된 것보다 우선하여 사용됩니다.

반환 값은 0에서 parties - 1 범위의 정수이며, 스레드마다 다릅니다. 이것은 특별한 하우스키핑을 수행할 스레드를 선택하는데 사용될 수 있습니다, 예를 들어:

i = barrier.wait()
if i == 0:
    # Only one thread needs to print this
    print("passed the barrier")

생성자에 action이 제공되면, 스레드 중 하나가 해제되기 전에 호출합니다. 이 호출로 에러가 발생하면, 장벽은 망가진 상태가 됩니다.

호출 시간제한이 만료되면, 장벽은 망가진 상태가 됩니다.

스레드가 기다리는 동안 장벽이 망가지거나 재설정되면 이 메서드는 BrokenBarrierError 예외를 발생시킬 수 있습니다.

reset()

장벽을 기본의 빈 상태로 되돌립니다. 대기 중인 모든 스레드는 BrokenBarrierError 예외를 수신합니다.

상태를 알 수 없는 다른 스레드가 있을 때 이 함수를 사용하려면 외부 동기화가 필요할 수 있습니다. 장벽이 망가지면 그냥 두고 새 장벽을 만드는 것이 좋습니다.

abort()

장벽을 망가진 상태로 보냅니다. 이로 인해 wait()에 대한 활성 또는 미래의 호출이 BrokenBarrierError로 실패합니다. 예를 들어 응용 프로그램의 교착 상태를 피하고자 스레드 중 하나를 중단해야 할 때 이를 사용하십시오.

스레드 중 하나가 잘못되는 것을 막기 위해 단순히 적절한 timeout 값으로 장벽을 만드는 것이 바람직 할 수 있습니다.

parties

장벽을 통과하는 데 필요한 스레드 수.

n_waiting

현재 장벽에서 대기 중인 스레드 수.

broken

장벽이 망가진 상태이면 True인 불리언.

exception threading.BrokenBarrierError

RuntimeError의 서브 클래스인, 이 예외는 Barrier 객체가 재설정되거나 망가질 때 발생합니다.

with 문으로 록, 조건 및 세마포어 사용하기

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()

현재 Lock, RLock, Condition, SemaphoreBoundedSemaphore 객체는 with 문 컨텍스트 관리자로 사용될 수 있습니다.