Python: GIL Kontextwechsel

8

Also, im Allgemeinen verstehe ich ziemlich gut, wie Global Interpreter Lock ( GIL) in Python funktioniert. Im Wesentlichen, während der Interpreter läuft, hält ein Thread die GIL für N Ticks (wobei N mit sys.setcheckinterval gesetzt werden kann), zu welchem ​​Zeitpunkt die GIL freigegeben wird und ein anderer Thread die GIL erwerben kann. Das passiert auch, wenn ein Thread eine E / A-Operation beginnt.

Was mich ein wenig verwirrt, ist, wie das alles mit C-Erweiterungsmodulen funktioniert.

Wenn Sie ein C-Erweiterungsmodul haben, das die GIL erwirbt und dann einen Python-Code mit PyEval_EvalCode ausführt, kann der Interpreter die GIL freigeben und sie einem anderen Thread geben? Oder behält der C-Thread, der die GIL erworben hat, die GIL dauerhaft, bis PyEval_EvalCode zurückkehrt und die GIL explizit in C freigegeben wird?

%Vor%     
Channel72 27.04.2013, 22:40
quelle

2 Antworten

2

Ja, der Dolmetscher kann immer die GIL freigeben; es wird es einem anderen Thread geben, nachdem es genügend Anweisungen interpretiert hat, oder automatisch, wenn es einige I / O-Operationen ausführt. Beachten Sie, dass seit dem letzten Python 3.x die Kriterien nicht mehr auf der Anzahl der ausgeführten Anweisungen basieren, sondern darauf, ob genügend Zeit verstrichen ist.

Um einen anderen Effekt zu erhalten, benötigen Sie einen Weg, um die GIL im "atomaren" Modus zu erhalten, indem Sie die GIL auffordern, nicht freigegeben zu werden, bis Sie sie explizit freigeben. Dies ist bisher nicht möglich (siehe jedoch Ссылка für eine experimentelle Version).

    
Armin Rigo 28.04.2013 12:03
quelle
1

Wie Armin sagte, kann die GIL innerhalb von PyEval_EvalCode veröffentlicht werden. Wenn es zurückkehrt, ist es natürlich wieder erworben.

Der beste Weg besteht darin, sicherzustellen, dass Ihr Code damit umgehen kann. ZB inkrementieren Sie alle Objekte, in denen Sie C-Zeiger haben, bevor die GIL freigegeben werden könnte. Seien Sie vorsichtig, wenn es Fälle geben könnte, in denen der Python-Code die gleiche Funktion erneut aufruft. Wenn Sie dort einen anderen Mutex haben, können Sie leicht in einen Dead-Lock geraten. Verwenden Sie rekursiv-sichere Mutexe, und während Sie darauf warten, sollten Sie die GIL freigeben, damit der ursprüngliche Thread solche Mutexe freigibt.

    
Albert 15.10.2013 15:41
quelle