[python] Lock

Vladimir Macek macek na sandbox.cz
Pondělí Únor 9 15:01:43 CET 2015


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 <mailto: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 <mailto:python na py.cz>
>     http://www.py.cz/mailman/listinfo/python
>
>     Visit: http://www.py.cz
>
>
>
>
> _______________________________________________
> Python mailing list
> python na py.cz
> http://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

------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://www.py.cz/pipermail/python/attachments/20150209/1428ad1f/attachment.html>


Další informace o konferenci Python