2013-02-17 18 views
5

Sono un po 'confuso su quando dovrei chiamare PyEval_InitThreads. In generale, capisco che PyEval_InitThreads deve essere chiamato ogni volta che viene utilizzato un thread non Python (cioè un thread che viene generato all'interno di un modulo di estensione).Quando si intende chiamare PyEval_InitTread?

Tuttavia, sono confuso se PyEval_InitThreads è per programmi C che incorporano l'interprete Python o programmi Python che importano moduli di estensione C o entrambi.

Quindi, se scrivo un modulo di estensione C che avvierà internamente un thread, devo chiamare PyEval_InitThreads durante l'inizializzazione del modulo?

Inoltre, PyEval_InitThreadsimplicitly acquires the Global Interpreter Lock. Quindi, dopo aver chiamato PyEval_InitThreads, presumibilmente la GIL deve essere rilasciata o si verificherà un deadlock. Quindi, come si rilascia il lucchetto? Dopo aver letto la documentazione, PyEval_ReleaseLock() sembra essere il modo per rilasciare GIL. Tuttavia, in pratica, se uso il seguente codice in un modulo di estensione C:

PyEval_InitThreads(); 
    PyEval_ReleaseLock(); 

... poi in fase di esecuzione Python si interrompe con:

Fatal Python error: drop_gil: GIL is not locked 

così come si fa rilasciare il GIL dopo l'acquisizione con PyEval_InitThreads?

+0

Provare senza 'PyEval_ReleaseLock()'. Il GIL è acquisito per una buona ragione; rilasciarlo prima di chiamare altre funzioni API C da Python sta andando in crash. –

risposta

3

La maggior parte delle applicazioni non ha bisogno di sapere nulla su PyEval_InitThreads().

L'unica volta che si dovrebbe usare è se l'applicazione incorporamento o il modulo di estensione sarà fare chiamate API Python C da più di un thread che essa stessa ha generato al di fuori di Python.

Non chiamare PyEval_ReleaseLock() in nessun thread che effettuerà in seguito chiamate API Python C (a meno che non lo si riacquisisca prima di quelli). In tal caso, devi utilizzare le macro Py_BEGIN_ALLOW_THREADS e Py_END_ALLOW_THREADS.

+1

Non capisco questa risposta. Supponendo che tu stia incorporando Python in un programma in C e tu abbia 20 thread di lavoro, chi dovrebbe chiamare PyEval_InitThreads e come fa ogni worker a rilasciare il lock mentre è fuori a fare altre cose così gli altri thread che devono fare del lavoro Python possono ottenere il GIL ? – DougN

+0

@DougN, sì sono d'accordo. La risposta è vaga (come lo sono purtroppo i documenti Python) –

+2

Se si sta incorporando il programma Python i a C, richiamarlo una volta per l'intero programma mentre si inizializza l'interprete Python incorporato prima di eseguire il primo codice Python. – gps

Problemi correlati