2009-04-29 13 views
7

C'è un modo per incorporare Python, consentire i callback da Python a C++, permettendo al codice Pythhon di generare thread ed evitare deadlock?Python incorporamento con thread - evitando deadlock?

Il problema è questo:

  • di rimettere in Python, ho bisogno di tenere il GIL. In genere, lo faccio ottenendo lo stato del thread principale quando creo l'interprete e poi usando PyEval_RestoreThread() per prendere GIL e scambiare lo stato del thread prima di chiamare in Python.

  • Quando chiamato da Python, potrebbe essere necessario accedere ad alcune risorse protette che sono protette da una sezione critica separata nel mio host. Ciò significa che Python manterrà il GIL (potenzialmente da qualche altro thread di quello inizialmente chiamato), e quindi tenterà di acquisire il mio blocco di protezione.

  • Quando si chiama in Python, potrebbe essere necessario mantenere gli stessi blocchi, perché, ad esempio, sto eseguendo un'iterazione su alcune raccolte di oggetti.

Il problema è che, anche se tengo la GIL quando chiamo in Python, Python può rinunciarvi, darlo a un altro thread, e poi quella chiamata filo nella mio ospite, in attesa di prendere l'host serrature. Nel frattempo, l'host può prendere i blocchi host e il blocco GIL e chiamare in Python. Ne risulta uno stallo.

Il problema qui è che Python rinuncia a GIL su un altro thread mentre ci ho chiamato. Questo è quello che ci si aspetta che faccia, ma rende impossibile il sequenziamento del blocco - anche se prima prendo GIL, poi prendo il mio lock, poi chiamo Python, Python chiamerà nel mio sistema da un altro thread, aspettandosi di prendere il mio lock (perché non sequenzia il GIL rilasciandolo).

Non riesco davvero a fare in modo che il resto del mio sistema utilizzi GIL per tutti i blocchi possibili nel sistema, e questo non funzionerebbe correttamente, perché Python potrebbe ancora rilasciarlo su un altro thread.

Non posso davvero garantire che il mio host non contenga alcun blocco durante l'accesso a Python, perché non ho il controllo di tutto il codice nell'host.

Quindi, è solo il caso che questo non può essere fatto?

+0

Potrebbe richiedere il codice C++ per contenere il GIL prima che acquisisca i blocchi dell'host? – Dave

risposta

2

"Quando si chiama in Python, potrei aver bisogno di tenere gli stessi lock, perché potrei dover iterare su alcuni gruppi di oggetti, per esempio."

Ciò indica spesso che un singolo processo con più thread non è appropriato. Forse questa è una situazione in cui più processi - ciascuno con un oggetto specifico dalla collezione - ha più senso.

Il processo indipendente, ciascuno con il proprio pool di thread, può essere più semplice da gestire.

+0

Un singolo processo è esattamente ciò di cui ho bisogno (il processo in questione è in realtà un plug-in del browser Web). Quindi, sfortunatamente, il tuo suggerimento non risponde o si applica alla mia domanda. –

+1

Si prega di aggiornare la domanda con fatti aggiuntivi - non aggiungere informazioni nei commenti. "Plug-in del browser Web" è una nuova informazione e appartiene alla domanda. –

2

Il codice che viene chiamato da python dovrebbe rilasciare GIL prima di prendere uno dei blocchi. In questo modo, credo che non possa entrare nel punto morto.

+0

Buona risposta. Ricorda che GIL esiste solo per proteggere le strutture di dati interne dell'interprete Python. Se un thread chiama in un codice non Python, può rilasciare GIL in modo sicuro mentre viene eseguito quel codice. – mhsmith

-1

Recentemente si è discusso di un problema simile nella lista pyopenssl. Temo che se cerco di spiegarlo, ho intenzione di sbagliare, quindi ti rimanderò allo the problem in question.