2011-02-07 4 views
4

나는 "나는 단지 그것을 이해하고 싶다"라는 질문을 가지고 있습니다. 먼저, 우분투에서 파이썬 2.6.5를 사용하고 있습니다.파이썬 스레드 및 소켓

그래서 스레드 모듈을 통해 파이썬의 스레드는 "스레드"일 뿐이며 GIL에게 특정 시간 동안 각 "스레드"의 코드 블록을 실행하도록 지시합니다. 사실 여기 실제 스레드가 아닙니다 ..

그래서 제가 한 스레드에서 블로킹 소켓을 가지고 있고 지금은 5 초 동안 데이터를 보내고 스레드를 차단하고 있습니다. 스레드를 차단하는 하나의 C 명령 (sock.send)이기 때문에 모든 프로그램을 차단할 것으로 예상됩니다. 그러나 주 스레드가 계속 실행되는 것을보고 놀랐습니다. 그러면 GIL이 send와 같은 차단 명령에 도달 한 후 나머지 코드를 어떻게 계속 실행할 수 있습니까? 여기에 진짜 스레드를 사용해야하지 않습니까?

감사합니다. 언급 wiki page on GIL

답변

11

파이썬은 "기본"스레드, 즉 기본 플랫폼의 스레드를 사용합니다. 리눅스에서는 pthread 라이브러리를 사용합니다 (관심이 있다면 here is the implementation).

파이썬 스레드의 특별한 점은 GIL입니다.이 전역 잠금을 보유하고있는 스레드 만 파이썬 데이터 구조를 수정할 수 있습니다. 따라서 많은 파이썬 연산은 다중 프로세서 코어를 사용할 수 없습니다. 차단 소켓이있는 스레드는 GIL을 보유하지 않으므로 다른 스레드에는 영향을 미치지 않습니다.

GIL은 종종 잘못 이해되어 사람들이 파이썬에서 스레드가 거의 쓸모 없다고 생각하게 만듭니다. GIL이 방지 할 수있는 유일한 방법은 여러 프로세서 코어에서 "순수한"Python 코드를 동시에 실행하는 것입니다. I/O를 차단하는 동안 스레드를 사용하여 GUI를 응답하게하거나 다른 코드를 실행하면 GIL이 영향을 미치지 않습니다. 스레드를 사용하여 NumPy/SciPy와 같은 일부 C 확장 모듈에서 여러 프로세서 코어를 동시에 실행하면 GIL이 영향을 미치지 않습니다.

6

파이썬이

주 잠재적으로 차단 또는 장기 실행 작업과 같은 I/O를, 이미지 처리 및 NumPy와 번호가 GIL 외부에서 발생, 재정.

+0

그래서 만약 내가 x 소켓 (또는 다른 I/O 개체), 그리고 그들 모두 백그라운드 (서버)에서 처리됩니다, 나는 2 진짜 스레드 : GIL과 GIL 밖에 있으므로 하나의 소켓 차단, 다른 차단됩니다 너무? 아니면 실제 스레드가 있습니까? (내가 말할 때 "x 개의 스레드가있다"는 의미 - 같은 시간에 x 개의 실제 스레드가있을 수 있습니다. 심지어 초 미만이라 할지라도) – RoeeK

+0

글쎄, 테스트 후 - 나는 실제 스레드 인 것 같습니다. 이제는 상황을 더 분명하게 만듭니다. – RoeeK

3

GIL (Global Interpreter Lock)은 잠금 장치이므로 아무 것도 실행하지 않습니다. 오히려 파이썬 인터프리터는 필요에 따라 잠금을 캡쳐하고 해제합니다. 일반적으로 Python 코드를 실행할 때는 잠금이 유지되지만 하위 수준 함수 (예 : sock.send)에 대해서는 잠금이 해제됩니다. 파이썬 스레드는 실제 OS 레벨 스레드이므로 스레드는 파이썬 코드를 병렬로 실행하지 않지만 하나의 스레드가 장기 실행 C 함수를 호출하면 GIL이 해제되고 처음 파이썬 코드 스레드가 끝날 때까지 다른 파이썬 코드 스레드가 실행될 수 있습니다.