Solve problems
in distributed environments, hoping to become the user's operating atomic execution from concurrent execution cases:
the order concurrent become serial execution, compared to pessimistic locking it possible to reduce the pressure on the database.
Principle
redis is single-threaded, concurrent requests come, let them line up will redis serial execution, internal redis is thread-safe
realization of the code
<ignore_js_op>
Taking into account the exception if the lock will never be able to appear at a single release, so do abnormal capture, regardless of whether an exception to the code to release the lock
<ignore_js_op>
Taking into account if single process server goes down, the lock will never be released
Option one: the start lock blank redis in
Option two: to lock set an expiration time, However, if the user's single operation that exceeds the expiration time lock, the order is not complete lock becomes ineffective. Long downtime expiration time set to restart immediately the problem can not be resolved
# Solution start a sub-thread, lock every 2s to reset the expiration time, the end of the main thread execution, the child thread is destroyed
<ignore_js_op>
Code destroying threads
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
from
threading
import
Thread
import
inspect
import
ctypes
def
_async_raise(tid, exctype):
"""raises the exception, performs cleanup if needed"""
tid
=
ctypes.c_long(tid)
if
not
inspect.isclass(exctype):
exctype
=
type
(exctype)
res
=
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
if
res
=
=
0
:
raise
ValueError(
"invalid thread id"
)
elif
res !
=
1
:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
None
)
raise
SystemError(
"PyThreadState_SetAsyncExc failed"
)
def
stop_thread(thread):
_async_raise(thread.ident, SystemExit)
def
a():
while
True
:
print
(
"123456789"
)
if
__name__
=
=
'__main__'
:
t
=
Thread(target
=
a)
t.start()
stop_thread(t)
|
Under the single remaining issues do not meet the first come first served
More technical information may concern: gzitcast