Pergunta

Eu estou trabalhando em incorporar python para c ++. Em alguns casos peculiar I exigem duas instâncias separadas do intérprete no mesmo segmento.

intérprete Can I envoltório Python para a ++ classe c e obter serviços de dois ou mais instâncias de classe?

Foi útil?

Solução

Eu tenho usado Py_NewInterpreter para diferentes intérpretes em diferentes tópicos, mas isso também deve funcionar por vários intérpretes dentro de um fio:

No segmento principal:

Py_Initialize();
PyEval_InitThreads();
mainThreadState = PyEval_SaveThread();

Para cada instância intérprete (em qualquer segmento):

// initialize interpreter
PyEval_AcquireLock();                // get the GIL
myThreadState = Py_NewInterpreter();
... // call python code
PyEval_ReleaseThread(myThreadState); // swap out thread state + release the GIL

... // any other code

// continue with interpreter
PyEval_AcquireThread(myThreadState); // get GIL + swap in thread state
... // call python code
PyEval_ReleaseThread(myThreadState);

... // any other code

// finish with interpreter
PyEval_AcquireThread(myThreadState);
... // call python code
Py_EndInterpreter(myThreadState);
PyEval_ReleaseLock();                // release the GIL

Note que você precisa de um myThreadState variável para cada instância intérprete!

Finalmente, o acabamento no segmento principal:

PyEval_RestoreThread(mainThreadState);
Py_Finalize();

Existem algumas restrições com o uso de várias instâncias intérprete (eles parecem não ser totalmente independente), mas na maioria dos casos, isso não parece causar problemas.

Outras dicas

Callin Py_Initialize() duas vezes não vai funcionar bem, no entanto Py_NewInterpreter pode trabalho, dependendo do que você está tentando fazer. Leia a documentação com cuidado, você tem que segurar o GIL ao chamar isso.

Você pode, mas eu recomendo que você não re-implementar um interpretador Python quando há uma implementação padrão. Use boost :: python para fazer a interface com o Python.

Eu não acho que você é a primeira pessoa a querer fazer isso, infelizmente, eu acredito que não é possível. Você é capaz de executar os interperters python como processos separados e uso RPC?

resposta

O mosaik não funcionou na minha situação onde meu módulo é um plug-in para um aplicativo host que já inicializa python. Eu era capaz de fazê-lo funcionar com o seguinte código.

// initialize interpreter
::PyEval_InitThreads();
::PyThreadState *mainThread = ::PyThreadState_Get();
myState = ::Py_NewInterpreter();
... // call python code
::PyThreadState_Swap(mainThread);

... // any other code

mainThread = ::PyThreadState_Swap(myState)
... // call python code
::PyThreadState_Swap(mainThread)

... // any other code

// finished with interpreter
mainThread = ::PyThreadState_Swap(myState)
::Py_EndInterpreter(myState);
::PyThreadState_Swap(mainThread)

Quando liguei PyEval_AcquireLock() o programa bloqueado e a função não retornou. Além disso, chamando PyEval_ReleaseThread(myState) parecia invalidar o intérprete também.

  • Você pode deixar que o python intérprete fora ao vivo do seu espaço de memória do aplicativo. Apenas incorporar o intérprete em uma DLL.
  • Você pode configurar e salvar contextos python para simular dois intérpretes diferentes.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top