2010-05-13 2 views
3

파이썬 인터프리터는 글로벌 인터프리터 잠금 기능을 가지고 있기 때문에 확장 기능은 다중 스레드 환경에서 가져와야한다는 것을 알고 있습니다. 그러나 Boost.Python HOWTO page은 확장 기능이 GIL을 릴리스하고 종료 할 때 다시 가져와야한다고 말합니다.Python 확장 기능 멀티 쓰레딩 설명

는 여기 추측 유혹에 저항 할, 그래서 나는 다음과 같은 경우에 GIL 잠금 패턴해야하는지 알고 싶습니다

  1. 확장은 파이썬에서 호출 (아마도 파이썬 스레드에서 실행).
  2. 확장의 배경 스레드는 Py_* 함수를 다시 호출합니다.

마지막 질문은 왜 링크 된 문서가 GIL을 공개하고 다시 취득해야한다고 말합니까?

답변

4

파이썬이 바이트 코드를 해석 할 때마다 GIL이 현재 실행중인 스레드에 의해 보류되고 있습니다. 다른 Python 쓰레드는 GIL을 획득 할 때까지 실행될 수 없다.

    그것은 전혀 아무것도 할 수
  1. : 인터프리터는 그 코드가 네이티브 코드로 호출 한

    GIL에 대한 두 가지 옵션이 있습니다.

  2. 이 작동하는 동안 GIL을 해제 한 후 기본 코드는 옵션 1을해야 파이썬의 실행에 다시 전화를 많이 만드는 경우 파이썬

에 반환하기 전에 재 취득 할 수 : 파이썬의 런타임을 호출 할 수 없다 안전하게 GIL을 가지고 있지 않으면 (GIL을 가지고 있지 않다면 GIL을 얻기 위해 전화하는 것과 같은 몇 가지 예외를 제외하고는).

네이티브 코드가 파이썬과 관련이없는 많은 작업을 수행하는 경우 옵션 2를 사용할 수 있습니다. GIL을 릴리스하자마자 Python이 다른 파이썬 스레드를 예약하여 일부 병렬 처리를 수행 할 수 있습니다 . GIL을 해제하지 않으면 부스트 코드가 실행되는 동안 파이썬의 다른 스레드가 실행할 수 없으므로 문서에서 GIL을 해제하고 다시 가져 오라고 말합니다.

이렇게하면 길을 풀기 전이나 다시 가져온 후에 Py_*에 대한 모든 액세스를 조심해야합니다. 따라서 GIL이 릴리스되는 동안리스트 또는 사전 요소와 같은 Python 데이터 유형에 안전하게 액세스 할 수 없으므로 데이터의 로컬 복사본을 만들어야 할 수도 있습니다.

GIL이 해제 된 상태에서 부스트 코드를 파이썬으로 다시 호출해야한다면 GIL을 획득하고, 전화를 걸고, GIL을 릴리스해야합니다. 파이썬이 GIL을 얻을 수있는 추가 작업이 필요하기 때문에 생성되지 않은 스레드에서 그러한 호출을하지 않도록하십시오.

+0

감사합니다. 이렇게하면 문제가 해결됩니다. 그러나 마지막으로 명확한 점이 하나 있습니다. 파이썬 코드가 기본 확장 코드를 호출 할 때 GIL을 해제 할 수 있습니다. 하지만 콜 스택은 네이티브 코드를 호출 할 때'PyObject_CallFunction','PyObject_Call'과 같은 파이썬 함수 호출을 포함합니다. 이 기능의 맥락에서 GIL을 해제하는 것이 안전한 이유는 무엇입니까? –

+0

이 함수는 스택이 풀려서 "반환"될 때까지는 아무 것도하지 않습니다. 그 때까지는 GIL을 다시 획득해야 작동 할 수 있습니다. –