[python] Lock

Jakub Vysoky jakub na borka.cz
Pondělí Únor 9 16:15:51 CET 2015


a protoze ve svete bezstavovych webovych workeru bychom se na lokalni
filesystem spolehat opravdu nemeli, tak kdyz uz kladivo, tak opravdove:
cili zamek v nejakej sdilenem ulozisti, treba v te databazi, coz jsme
pomerne blizko i tem transakcim.

2015-02-09 15:01 GMT+01:00 Vladimir Macek <macek na sandbox.cz>:

>  Existuje na to i opravdu kladivo: souborovy zamek.
>
> Na lokalnim souborovem systemu mas zaruceno, ze v kriticke sekci se bude
> pohybovat jen jeden thread. Pouzivam i u webovych aplikaci v sekcich, kde
> potrebuju uplnou jistotu.
>
> Implementaci prevzatou z webu najdes napr. v me sade nastroju:
>
>     https://github.com/tuttle/python-useful/blob/master/useful/filelock.py
>
> Lze komplet nainstalovat prikazem:
>
> $ pip install useful
>
> Drobna ukazecka:
>
> $ virtualenv /tmp/test-lock && /tmp/test-lock/bin/pip install useful &&
> /tmp/test-lock/bin/python
> New python executable in /tmp/test-lock/bin/python
> Installing setuptools, pip...done.
> Downloading/unpacking useful
>   Downloading useful-0.6.4-py2-none-any.whl (40kB): 40kB downloaded
> Installing collected packages: useful
> Successfully installed useful
> Cleaning up...
> Python 2.7.6 (default, Mar 22 2014, 22:59:38)
> [GCC 4.8.2] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>
> >>> import time>>> from multiprocessing.dummy import Pool as ThreadPool>>> >>> from useful.filelock import FileLock>>> >>> def worker_normal(job):...     print "Start", job...     time.sleep(1)...     print "End", job...     return job.lower()... >>> def worker_critical(job):...     with FileLock('/tmp/test-lock'):...         print "Start", job...         time.sleep(1)...         print "End", job...         return job.lower()... >>> def run_with(worker):...     start = time.time()...     pool = ThreadPool(5)...     print pool.map(worker, 'ABCDEFGHI')...     pool.close()...     pool.join()...     print "Completion time with %s: %d secs" % (worker, time.time()-start)... >>> run_with(worker_normal)
> Start Start AStart B
>  Start
>  DC
>
> Start E
> EndEnd End  CEndEnd A
> D
> BE
>
> Start F
>
> Start G
>  Start H
> Start I
> End F
>  EndEnd  G
> H
> End I['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
> Completion time with <function worker_normal at 0xb6f9dae4>: 2 secs>>> run_with(worker_critical)
> Start A
> End A
> Start F
> End F
> Start G
> End G
> Start H
> End H
> Start I
> End I
> Start E
> End E
> Start D
> End D
> Start C
> End C
> Start B
> End B['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
> Completion time with <function worker_critical at 0xb6f9ddf4>: 9 secs>>>
>
>
> V.
>
>
> On 9.2.2015 13:43, Petr Blahos wrote:
>
> Ahoj,
>
>  no, jestli ten kód vypadá opravdu přesně takto, tak dělá tohle:
> * vytvoří úplně nový zámek a acquirene ho.
> * udělá to sql
> * releasene zámek.
> No a druhý případný thread dělá to stejné:
>  * vytvoří úplně nový zámek a acquirene ho.
> * udělá to sql
> * releasene zámek.
>  Takže nic ničemu v ničem nezabrání.
>
>  Tohle se ale dělá transakcema, a pokud máš MyISAm engine, tak spíš
> zamčením
> patřičných tabulek:
> "LOCK TABLES platby READ"
> ...
> "UNLOCK TABLES"
>
>  --
>  Petr
>
>
>
>
>
> 2015-02-09 11:42 GMT+01:00 mtip <mtip na atlas.cz>:
>
>> Ahoj,
>> narazil jsem na problém se zámkem.
>>
>> Mám  aplikaci  na web serveru, která ukládá příznak booolean Zaplaceno
>> do MySQL databáze.
>> Občas  se ale stane, že potvrzení platby přijde najednou ve stejný čas
>> ze dvou zdrojů. Chtěl jsem to vyřešit zámkem, což ale nepomůže.
>>
>> Princip kódu:
>>
>> from threading import Lock
>> lock = Lock()
>> lock.acquire()
>> try:
>>     mysql_cursor.execute("SELECT Zaplaceno FROM platby WHERE Id=%s", (1,))
>>     if mysql_cursor.fetchall()[0]['Zaplaceno'] == 0:
>>         mysql_cursor.execute("UPDATE Zaplaceno=1 FROM platby WHERE
>> Id=%s", (1,))
>>         mysql_connection.commit()
>>         # dalsi zpracovani platby...
>> finally:
>>     lock.release()
>>
>>
>>
>> Pokud je request spuštěn 2x ve stený čas provede se zpracování platby 2x.
>> Přičemž ale SELECT je pod zámkem, takže by se neměl provést mezi SELECT a
>> UPDATE druhého threadu.
>> Netušíte, kde může být problém?
>>
>> Díky za odpovědi.
>>
>> Mirek
>>
>> _______________________________________________
>> Python mailing list
>> python na py.cz
>> http://www.py.cz/mailman/listinfo/python
>>
>> Visit: http://www.py.cz
>>
>
>
>
> _______________________________________________
> Python mailing listpython na py.czhttp://www.py.cz/mailman/listinfo/python
>
> Visit: http://www.py.cz
>
>
>
> --
> :  Vladimir Macek  :  http://macek.sandbox.cz  :  +420 608 978 164
> :  UNIX && Dev || Training  :  Python, Django  :  PGP key 97330EBD
>
>
> _______________________________________________
> Python mailing list
> python na py.cz
> http://www.py.cz/mailman/listinfo/python
>
> Visit: http://www.py.cz
>



-- 
Jakub Vysoky

mob: +420 605 852 377
jab: jakub.vysoky na gmail.com
twit: https://twitter.com/kvbik
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://www.py.cz/pipermail/python/attachments/20150209/3f1bc7d5/attachment.html>


Další informace o konferenci Python