# `_thread` — 저수준 스레드 API

이 모듈은 다중 스레드(경량 프로세스 (light-weight processes) 나 태스크 (tasks)라고도 합니다)로 작업하는데 필요한 저수준 기본 요소를 제공합니다 — 전역 데이터 공간을 공유하는 여러 개의 제어 스레드를 뜻합니다. 동기화를 위해서, 간단한 록(뮤텍스 (mutexes)나 이진 세마포어 (binary semaphores)라고도 합니다)이 제공됩니다. `threading` 모듈은 이 모듈 위에 구축되어 사용하기 쉬운 고수준의 스레딩 API를 제공합니다.

버전 3.7에서 변경: 이 모듈은 선택 사항이었지만, 이제는 항상 사용할 수 있습니다.

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

exception `_thread.``error`

  스레드 특정 에러에서 발생합니다.

  버전 3.3에서 변경: 이것은 이제 내장 `RuntimeError`의 동의어입니다.

`_thread.``LockType`

  이것은 록 객체의 형입니다.

`_thread.``start_new_thread`(function, args[, kwargs])

  새 스레드를 시작하고 식별자를 반환합니다. 스레드는 인자 목록 args(튜플이어야 합니다)로 함수 function을 실행합니다. 선택적 kwargs 인자는 키워드 인자 딕셔너리를 지정합니다.

  함수가 반환되면, 스레드는 조용히 종료합니다.

  함수가 처리되지 않은 예외로 종료되면, 예외를 처리하기 위해 `sys.unraisablehook()`이 호출됩니다. 훅 인자의 object 어트리뷰트는 function입니다. 기본적으로, 스택 트레이스가 인쇄된 다음 스레드가 종료합니다 (하지만 다른 스레드는 계속 실행됩니다).

  함수가 `SystemExit` 예외를 발생시키면, 조용히 무시됩니다.

  버전 3.8에서 변경: `sys.unraisablehook()`은 이제 처리되지 않은 예외를 처리하는 데 사용됩니다.

`_thread.``interrupt_main`()

  메인 스레드에 도달한 `signal.SIGINT` 시그널의 효과를 시뮬레이트합니다. 스레드는 이 함수를 사용하여 메인 스레드를 인터럽트 할 수 있습니다.

  `signal.SIGINT`가 파이썬에 의해 처리되지 않으면 (`signal.SIG_DFL`이나 `signal.SIG_IGN`으로 설정됩니다), 이 함수는 아무것도 하지 않습니다.

`_thread.``exit`()

  `SystemExit` 예외를 발생시킵니다. 잡히지 않으면, 스레드가 조용히 종료되도록 합니다.

`_thread.``allocate_lock`()

  새로운 록 객체를 반환합니다. 록의 메서드는 아래에 설명되어 있습니다. 록은 초기에 잠금 해제되어 있습니다.

`_thread.``get_ident`()

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

`_thread.``get_native_id`()

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

  가용성: 윈도우, FreeBSD, 리눅스, macOS, OpenBSD, NetBSD, AIX.

  버전 3.8에 추가.

`_thread.``stack_size`([size])

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

  가용성: 윈도우, POSIX 스레드가 있는 시스템.

`_thread.``TIMEOUT_MAX`

  `Lock.acquire()`의 timeout 매개 변수에 허용되는 최댓값. 이 값보다 큰 timeout을 지정하면 `OverflowError`가 발생합니다.

  버전 3.2에 추가.

록 객체에는 다음과 같은 메서드가 있습니다:

`lock.``acquire`(waitflag=1, timeout=-1)

  선택적 인자가 아무것도 없으면, 이 메서드는 조건 없이 록을 획득합니다, 필요하면 다른 스레드가 록을 해제할 때까지 대기합니다 (한 번에 하나의 스레드만 록을 획득할 수 있습니다 — 이것이 록의 존재 이유입니다).

  정수 waitflag 인자가 있으면, 행동은 그 값에 따라 다릅니다: 0이면 대기하지 않고 즉시 획득할 수 있을 때만 록이 획득되고, 0이 아니면 위와 같이 록이 조건 없이 획득됩니다.

  부동 소수점 timeout 인자가 있고 양수이면, 반환하기 전에 대기할 최대 시간을 초로 지정합니다. 음의 timeout 인자는 제한 없는 대기를 지정합니다. waitflag이 0이면 timeout을 지정할 수 없습니다.

  록이 성공적으로 획득되면 반환 값은 `True`이고, 그렇지 않으면 `False`입니다.

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

  버전 3.2에서 변경: 록 획득은 이제 POSIX의 시그널에 의해 중단될 수 있습니다.

`lock.``release`()

  록을 해제합니다. 록은 반드시 이전에 획득된 것이어야 하지만, 반드시 같은 스레드에 의해 획득된 것일 필요는 없습니다.

`lock.``locked`()

  록의 상태를 반환합니다: 어떤 스레드에 의해 획득되었으면 `True`, 그렇지 않으면 `False`를 반환합니다.

이러한 메서드 외에도, `with` 문을 통해 록 객체를 사용할 수도 있습니다, 예를 들어:

    import _thread

    a_lock = _thread.allocate_lock()

    with a_lock:
        print("a_lock is locked while this executes")

주의 사항:

- 스레드는 이상한 방식으로 인터럽트와 상호 작용합니다: `KeyboardInterrupt` 예외는 임의의 스레드가 수신합니다. (`signal` 모듈을 사용할 수 있으면, 인터럽트는 항상 메인 스레드로 갑니다.)

- `sys.exit()`를 호출하거나 `SystemExit` 예외를 발생시키는 것은 `_thread.exit()`를 호출하는 것과 동등합니다.

- 록에 대한 `acquire()` 메서드를 인터럽트 할 수 없습니다 — 록이 획득된 후에 `KeyboardInterrupt` 예외가 발생합니다.

- 메인 스레드가 종료할 때, 다른 스레드가 살아남는지는 시스템이 정의합니다. 대부분 시스템에서, `try` … `finally` 절을 실행하거나 객체 파괴자(destructor)를 실행하지 않고 강제 종료됩니다.

- 메인 스레드가 종료할 때, (`try` … `finally` 절이 적용되는 것을 제외하고는) 일반적인 정리 작업을 수행하지 않으며, 표준 I/O 파일은 플러시 되지 않습니다.