"_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* 인자는 키워드 인자 딕셔너리를 지정합니다. 함수가 반환되면,
   스레드는 조용히 종료합니다. 함수가 처리되지 않은 예외로 종료되면,
   스택 트레이스가 인쇄된 다음 스레드가 종료합니다 (하지만 다른 스레드
   는 계속 실행됩니다).

_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.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 파일은 플러
  시 되지 않습니다.
