2013-04-27 5 views
8

그래서 일반적으로 파이썬에서 Global Interpreter Lock (GIL)이 어떻게 작동하는지 꽤 잘 알고 있습니다. 본질적으로 인터프리터가 실행 중일 때 한 스레드는 N tick 당 GIL을 보유하고 (Nsys.setcheckinterval을 사용하여 설정할 수 있음), GIL이 해제되고 다른 스레드가 GIL을 획득 할 수 있습니다. 하나의 스레드가 I/O 작업을 시작하는 경우에도 발생합니다.파이썬 : GIL 컨텍스트 스위칭

제가 약간 혼란스러워하는 점은이 모든 것이 C 확장 모듈과 어떻게 작동하는지입니다.

GIL을 얻는 C 확장 모듈이 있고 PyEval_EvalCode을 사용하여 일부 파이썬 코드를 실행하는 경우 인터프리터는 GIL을 릴리스하고 다른 스레드에 줄 수 있습니까? 또는 GIL을 얻은 C 스레드는 PyEval_EvalCode이 반환되고 GIL이 C에서 명시 적으로 릴리스 될 때까지 GIL을 영구적으로 유지합니까?

PyGILState gstate = PyGILState_Ensure(); 

.... 

/* Can calling PyEval_EvalCode release the GIL and let another thread acquire it?? */ 
PyObject* obj = PyEval_EvalCode(code, global_dict, local_dict); 

PyGILState_Release(gstate); 

답변

2

예, 해석기는 항상 GIL을 릴리스 할 수 있습니다. 충분한 지시 사항을 해석 한 후에 다른 스레드로 전달하거나, 일부 I/O를 수행하면 자동으로이를 제공합니다. 최근의 Python 3.x 이후로는 더 이상 실행 된 명령어의 수를 기준으로하지 않고 충분한 시간이 경과했는지 여부를 기준으로합니다.

다른 효과를 얻으려면 명시 적으로 해제 할 때까지 GIL을 해제하지 말고 "원자"모드에서 GIL을 가져 오는 방법이 필요합니다. 지금까지는 불가능합니다 (실험 버전은 https://bitbucket.org/arigo/cpython-withatomic 참조).

+0

내 [관련 질문] (http://stackoverflow.com/questions/29317120/forcing-a-thread-to-block-all-other-threads-from-executing)을 참조하십시오. 귀하의 진술과 Python Cookbook의 진술 사이의 불일치를 해결하는 방법을 이해하지 못합니다. – max

+0

[Albert 's answer] (http://stackoverflow.com/a/29328066)를 참조하십시오. –

1

Armin이 말했듯이, GIL은 PyEval_EvalCode 안에 공개 될 수 있습니다. 그것이 돌아 오면, 물론 다시 획득하게됩니다.

가장 좋은 방법은 코드가이를 처리 할 수 ​​있는지 확인하는 것입니다. 예를 들어, GIL이 해제되기 전에 C 포인터가있는 모든 오브젝트를 incrementf하십시오. 또한 파이썬 코드가 다시 똑같은 기능을 호출하는 경우가 있을지 조심하십시오. 거기에 다른 뮤텍스가 있다면, 당신은 쉽게 데드 록으로 끝날 수 있습니다. 재귀 적으로 안전한 뮤텍스를 사용하고 기다리는 동안 GIL을 해제하여 원래 스레드가 그러한 뮤텍스를 해제 할 수 있도록해야합니다.

관련 문제