2013-02-17 4 views
5

Я немного смущен, когда я должен позвонить PyEval_InitThreads. В общем, я понимаю, что PyEval_InitThreads должен вызываться всякий раз, когда используется поток не-Python (т. Е. Поток, который порождается в модуле расширения).Когда вызывается PyEval_InitThreads?

Однако я смущен, если PyEval_InitThreads предназначен для программ на языке C, которые включают интерпретатор Python или программы Python, которые импортируют модули C-расширения или и то, и другое.

Итак, если я пишу модуль расширения C, который будет внутренне запускать поток, мне нужно вызвать PyEval_InitThreads при инициализации модуля?

Также, PyEval_InitThreadsimplicitly acquires the Global Interpreter Lock. Поэтому, после звонка PyEval_InitThreads, предположительно, GIL должен быть освобожден или произойдет взаимоблокировка. Итак, как вы освобождаете замок? После прочтения документации PyEval_ReleaseLock(), похоже, является способом выпуска GIL. Однако, на практике, если я использую следующий код в модуле расширения C:

PyEval_InitThreads(); 
    PyEval_ReleaseLock(); 

... Затем во время выполнения Python Прерывает с:

Fatal Python error: drop_gil: GIL is not locked 

Итак, как вы отпустите GIL после приобретения это с PyEval_InitThreads?

+0

Попробуйте использовать 'PyEval_ReleaseLock()'. GIL приобретается по уважительной причине; выпуская его перед вызовом других функций API C из Python. –

ответ

3

Большинство приложений никогда не нужно знать о PyEval_InitThreads().

Единственный раз, когда вы должны использовать его, если ваше приложение внедрения или модуль расширения будет делать вызовы API Python C из более чем одного потока , он породил себя вне Python.

Не вызывайте PyEval_ReleaseLock() в любом потоке, который позже будет создавать вызовы API Python C (если только вы не повторно приобретете их до этого). В этом случае вы должны действительно использовать макросы Py_BEGIN_ALLOW_THREADS и Py_END_ALLOW_THREADS.

+1

Я не понимаю этого ответа. Предполагая, что вы внедряете Python в программу на C, и у вас есть 20 рабочих потоков, которые должны вызывать PyEval_InitThreads, и как каждый рабочий освобождает блокировку, пока он не выполняет другие действия, поэтому другие потоки, которые должны выполнять некоторые работы на Python, могут получить GIL ? – DougN

+0

@ DougN, да, я согласен. Ответ является неопределенным (как и сами документы Python, к сожалению) –

+2

Если вы внедряете программу Python i C, вызовите ее один раз для всей программы, когда вы инициализируете встроенный интерпретатор Python, прежде чем запускать свой первый код Python. – gps

 Смежные вопросы

  • Нет связанных вопросов^_^