Hodne lidi si stezuje na GIL. Ale vlakna v mnoha pripadech zjednodusuji programovani a nemusi byt je kvuli zvysovani vykonu. Proste vytvoreni threadu na nejakou ulohu je mnohdy jednodussi nez delat nejake timery apod. V GUI aplikacich je to jeste vice markantni.
Jinak je asi lepsi pouzivat try finally na odemykani zamku. Kdyz nastane vyjimka v try, tak nemate deadlock. Mozna jeste hezci je reseni pomoci nejakeho synchronized dekoratoru, ktery zamyka celou funkci. Proste neco jako scoped lock. Pak uz se chyba jen tezko dela.
Ano, try - finally se hodi. Dokonce na to autori Pythonu mysleli tak, ze existuje takova pekna konstrukce, neco jako
from threading import Lock
with Lock():
(...)
Nekde jsem to videl a melo by to samo odemykat zamek, ale nevim, jak to nakonec funguje, kdo chce vedet vic, ma tady PEP. Pokud pisu neco nepresne, tak se omlouvam, nemam to nastudovane...
Problém je v tom, že with Lock(): vytvoří zámek a hned si ho vezme (navíc zámek není přiřazený do žádné proměnné, takže se nedá použít v jiném vlákně). Standardní postup je připravit si někde zámek a pak ho opakovaně používat v jednotlivých vláknech (viz uvedený příklad).
Fungování je jednoduché: třída implementuje metody __enter__() a __exit__(), při vyhodnocování výrazu v konstrukci with se zavolá __enter__(), při ukončení těla bloku (i v případě vyvolání výjimky, stejně jako u finally:) se zavolá __exit__(). Takže Lock v __enter__() zavolá self.acquire(), v __exit__() je self.release() a je vymalováno.