2012-11-02 4 views
13

http://bugs.python.org/msg160297 읽기 파이썬 스레딩 버그를 볼 수있는 방법을 이해이 예외, 내가 보여 스티븐 화이트로 작성된 간단한 스크립트를

Exception AttributeError: AttributeError("'_DummyThread' object has no attribute '_Thread__block'",) in <module 'threading' 

스티븐 화이트의 소스 코드를 감안할 때 (HTTP와 파이썬 스레딩 버그까지 : //bugs.python .org/file25511/bad-thread.py),

import os 
import thread 
import threading 
import time 

def t(): 
    threading.currentThread() # Populate threading._active with a DummyThread 
    time.sleep(3) 

thread.start_new_thread(t,()) 

time.sleep(1) 

pid = os.fork() 
if pid == 0: 
    os._exit(0) 

os.waitpid(pid, 0) 

이 오류가 해결되도록 어떻게 다시 작성하겠습니까?

+0

제게'time.sleep (3)'으로 다시 쓸 수 있습니다. 재 작성된 프로그램이 실제로해야 할 일을 지정해야한다고 생각합니다. –

+3

@JanneKarila이 프로그램은 파이썬 버그를 보여 주며 파이썬 2.7에서 실행하면 볼 수 있습니다. 요청은 버그를 수정 한 Python 릴리스로 업그레이드하지 않고 버그를 해결하는 것입니다. – user4815162342

답변

33

The bug 때문에 os.fork()를 호출 한 후 자원을 정리하기 위해 호출 한 외국 스레드에서 threading.currentThread()를 호출 할 때 threading API에 의해 만들어진 더미 스레드 객체 사이의 나쁜 상호 작용, 그리고 threading._after_fork 기능, 발생합니다.

__stop의 무 연산 구현과 파이썬의 소스, 원숭이 패치 threading._DummyThread을 수정하지 않고 버그를 해결하려면 : 버그의 원인이 가장 Richard Oudkerkcooyeah로 의견 좁혀되어

import threading 
threading._DummyThread._Thread__stop = lambda x: 42 

.

  1. threading 모듈은 threading.currentThread()가 아니라 threading API 호출에 의해 생성 된 스레드에서 호출 할 수 있습니다 : 무슨 일 다음이다. 그런 다음 Thread API의 매우 제한된 하위 집합을 지원하는 "더미 스레드"인스턴스를 반환하지만 현재 스레드를 식별하는 데는 여전히 유용합니다.

  2. threading._DummyThreadThread의 하위 클래스로 구현됩니다. Thread 인스턴스에는 일반적으로 인스턴스에 할당 된 OS 수준 잠금에 대한 참조를 유지하는 내부 호출 가능 (self.__block)이 포함됩니다. self.__block을 사용하는 public Thread 메서드는 _DummyThread으로 모두 오버라이드되므로 _DummyThread의 생성자는 의도적으로 self.__block을 삭제하여 OS 수준의 잠금을 해제합니다.

  3. threading._after_fork는 캡슐화를 중단하고 __stop가 호출되기 위하여 의미되지 않았다 더미 사람을 포함하여 등록 된 모든 스레드의 개인 Thread.__stop 메소드를 호출합니다. 더미 스레드는 __stop에 대해 알지 못하기 때문에 Thread에서이 스레드를 상속하며 그 구현은 행복하지 않게 개인 __block 속성에 액세스합니다 (즉, 파이썬에 의해 시작된 것이 아니기 때문에 파이썬에 의해 중지되지 않습니다). _DummyThread 인스턴스에 존재합니다. 이 액세스는 마침내 오류를 발생시킵니다. __block 삭제할 때

버그 modifying Thread.__stop not to break하여 2.7 지점에 고정된다. __stop_stop으로 철자가 있으며 보호되므로 3.x 분기는 overriding _DummyThread's _stop to do nothing으로 수정합니다.

+0

아 ... 이제 알 겠어 ... 고마워! –

+0

뛰어난 설명! –

관련 문제