동시성:C/C++로 작성된 파이썬 확장자는 글로벌 인터프리터 잠금의 영향을 받습니까?
Python의 가장 큰 장점 중 하나는 코드의 프로세서 집약적인 부분의 속도를 높이기 위해 C와 C++ 확장자를 쉽게 쓸 수 있다는 것입니다.이러한 확장 기능은 글로벌 인터프리터 잠금 기능을 피할 수 있는 것일까요, 아니면 GIL의 제한도 받을 수 있을까요? 그렇지 않다면, 이러한 "확장 용이성"은 이전에 생각했던 것보다 훨씬 더 치명적인 기능입니다.저는 단순한 예/아니오가 답이 아니라고 생각하지만 확신할 수 없어서 스택 오버플로우에 대한 질문을 드립니다.
예, 확장(Python에서 호출된 C 루틴)에 대한 호출은 여전히 GIL의 대상입니다.
그러나 Python VM에 제어권을 반환하기 전에 다시 할당하도록 주의해야 하는 한 GIL을 C 확장 내에서 수동으로 해제할 수 있습니다.
하십시오 .Py_BEGIN_ALLOW_THREADS그리고.Py_END_ALLOW_THREADS매크로: http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock
Python에 대한 C/C++ 확장자는 GIL에 구속되지 않습니다.하지만, 여러분은 정말로 여러분이 무엇을 하고 있는지 알 필요가 있습니다.http://docs.python.org/c-api/init.html 에서:
글로벌 인터프리터 잠금은 포인터를 현재 스레드 상태로 보호하는 데 사용됩니다.잠금을 해제하고 스레드 상태를 저장할 때는 잠금을 해제하기 전에 현재 스레드 상태 포인터를 가져와야 합니다(다른 스레드가 즉시 잠금을 획득하고 자체 스레드 상태를 글로벌 변수에 저장할 수 있으므로).반대로, 잠금을 획득하고 스레드 상태를 복원할 때, 스레드 상태 포인터를 저장하기 전에 잠금을 획득해야 합니다.
왜 내가 이 일에 대해 그렇게 상세하게 얘기하고 있는 거지?C로 스레드를 생성할 때 글로벌 인터프리터 잠금이 없거나 스레드 상태 데이터 구조가 없기 때문입니다.이러한 스레드는 먼저 스레드 상태 데이터 구조를 생성한 다음 잠금을 획득하고 마지막으로 스레드 상태 포인터를 저장하여 부트스트랩을 실행해야 Python/C API 사용을 시작할 수 있습니다.작업이 완료되면 스레드 상태 포인터를 재설정하고 잠금을 해제한 후 마지막으로 스레드 상태 데이터 구조를 해제해야 합니다.
Check out Cython, it has similar syntax to Python but with a few constructs like "cdef", fast numpy access functions, and a "with nogil" statement (which does what it says).
If you’re writing your extension in C++, you can use RAII to easily and legibly write code manipulating the GIL. I use this pair of RAII structlets:
namespace py {
namespace gil {
struct release {
PyThreadState* state;
bool active;
release()
:state(PyEval_SaveThread()), active(true)
{}
~release() { if (active) { restore(); } }
void restore() {
PyEval_RestoreThread(state);
active = false;
}
};
struct ensure {
PyGILState_STATE* state;
bool active;
ensure()
:state(PyGILState_Ensure()), active(true)
{}
~ensure() { if (active) { restore(); } }
void restore() {
PyGILState_Release(state);
active = false;
}
};
}
}
… allowing the GIL to be toggled for a given block (in a semantic manner that may seem dimly familiar for any context-manager Pythonista fans):
PyObject* YourPythonExtensionFunction(PyObject* self, PyObject* args) {
Py_SomeCAPICall(…); /// generally, if it starts with Py* it needs the GIL
Py_SomeOtherCall(…); /// ... there are exceptions, see the docs
{
py::gil::release nogil;
std::cout << "Faster and less block-y I/O" << std::endl
<< "can run inside this block -" << std::endl
<< "unimpeded by the GIL";
}
Py_EvenMoreAPICallsForWhichTheGILMustBeInPlace(…);
}
… Indeed, personally also I find the ease of extending Python, and the level of control one has over the internal structures and state, a killer feature.
ReferenceURL : https://stackoverflow.com/questions/651048/concurrency-are-python-extensions-written-in-c-c-affected-by-the-global-inter
'programing' 카테고리의 다른 글
| $.ajax 및 JSONP. 구문 분석 오류 및 탐지되지 않은 구문 오류:예기치 않은 토큰: (0) | 2023.09.11 |
|---|---|
| Tomcat에서 Oracle을 사용하여 JNDI 데이터 원본 설정 (0) | 2023.09.11 |
| jQuery를 사용하여 팝업에서 입력 유형="file"에서 선택한 이미지를 미리 보는 방법은 무엇입니까? (0) | 2023.09.11 |
| 파이썬에서 문자열의 크기(길이)를 구하는 방법? (0) | 2023.09.11 |
| MsgBox 예/Excel VBA 없음 (0) | 2023.09.11 |