[python] multithreading & mutable sequence types
Radek Kanovsky
rk na dat.cz
Pondělí Říjen 25 13:49:12 CEST 2004
On Mon, Oct 25, 2004 at 11:02:52AM +0200, Marek Schmidt wrote:
> Dobrý den,
>
> s Pythonem teprve začínám a tak ještě nejsem příliž zběhlý v hledání
> odpovědí na otázky... snažil jsem se... :-)
>
> Jsou operace s pythonovským seznamem thread-safe?
Obecne nejsou zadne operace v pythonu thread-safe, ale konkretne append
a pop nad seznamem jo, protoze jsou implementovane v C a behem jejich
vykonavani je zamceny Global Interpreter Lock (GIL) a nikdo druhy by
nemel mit sanci neco s tim seznamem udelat. Funkce/metody psane v C
mohou GIL explicitne odemknout, pokud na neco cekaji (typicky na I/O),
ale tyto dve to nedelaji. Nicmene asi neni dobre na to spolehat a navic
to urcite plati jenom CPythonu. Jython, IronPython a dalsi odrudy se
mohou chovat odlisne (neznam).
> Potřebuji udělat něco takového:
>
> class KnightWhoSayNi(threading.Thread):
> def __init__(self):
> ...
> self.semafor = threading.Semaphore(0)
> self.queue = []
>
> def queueSayNi(self, target):
> self.queue.append(target)
> self.semafor.release()
>
> def run(self):
> while True:
> self.semafor.acquire()
> target = self.queue.pop(0)
>
> sayNiToTarget(target)
>
>
> queueSayNi se bude volat z jiných threadů. Můj dotaz pochopitelně zní:
> Je bezpečné to udělat takto a nebo je nutné operace s queue uzavřít mezi
> lock.acquire a lock.release? (případně, nejde to vše udělat nějak úplně
> jinak a lépe? :-)
Ja bych na tohle pouzil asi threading.Condition. Moc se mne nelibi
ono acquire/release v ruznych metodach.
[...]
def __init__ (self) :
....
self.cond = threading.Condition()
self.queue = []
def queueSayNi(self, target):
self.cond.acquire()
self.queue.append(target)
self.cond.notify()
self.cond.release()
def run(self):
while True:
self.cond.acquire()
while not self.queue :
self.cond.wait()
target = self.queue.pop(0)
self.cond.release()
sayNiToTarget(target)
Pokud je seznam prazdny, odemce cond.wait() zamek a ceka na cond.notify().
cond.notify() je volano po vlozeni noveho prvku a to vzbudi cekajici
cond.wait(). Po navratu z cond.wait() je zamek opet zamceny.
Ni! Ni! Ni! Ni! Ni! Ni!
RadekK
Další informace o konferenci Python