[python] multithreading & mutable sequence types
Marek Schmidt
xschmi01 na stud.fit.vutbr.cz
Pondělí Říjen 25 14:13:40 CEST 2004
Radek Kanovsky wrote:
> 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.
Aha! Tak takhle se da pouzit Condition.. diky moc!
> Ni! Ni! Ni! Ni! Ni! Ni!
Od ted je to KnightWhoTillRecentlySaidNi
> RadekK
Další informace o konferenci Python