**分布式鎖,是指在分布式的部署環境下,通過鎖機制來讓多客戶端互斥的對共享資源進行訪問。
訊號量的本質也是一種資料操作鎖,它本身不具有資料交換的功能,而是通過控制其他的通訊資源來實現程序間通訊,從而負責資料操作的互斥與同步。
本實訓專案的主要內容是使用 redis 構建鎖和訊號量,進一步提高 redis 效能。我們將通過構建簡易鎖,超時限製鎖,計數訊號量和公平訊號量來掌握分布式鎖與訊號量的相關知識。
**簡易鎖
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import uuid
import time
import redis
conn = redis.redis(
)# 獲得鎖
defacquire_lock
(lockname, acquire_timeout=5)
:# 請在下面完成要求的功能
#********* begin *********#
identifier =
str(uuid.uuid4())
end = time.time(
)+ acquire_timeout
while time.time(
)< end:
if conn.setnx(
'lock:'
+ lockname, identifier)
:return identifier
time.sleep(
0.001
)return
false
#********* end *********#
# 釋放鎖
defrelease_lock
(lockname, identifier)
:# 請在下面完成要求的功能
#********* begin *********#
pipe = conn.pipeline(
) lockname =
'lock:'
+ lockname
while
true
:try
: pipe.watch(lockname)
if pipe.get(lockname)
== identifier:
pipe.delete(lockname)
return
true
pipe.unwatch(
)break
except redis.exceptions.watcherror:
pass
return
false
#********* end *********#
超時限製鎖
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import uuid
import time
import redis
conn = redis.redis(
)# 獲得超時限製鎖
defacquire_lock_with_timeout
(lockname, acquire_timeout=
10, lock_timeout=10)
:# 請在下面完成要求的功能
#********* begin *********#
identifier =
str(uuid.uuid4())
lockname =
'lock:'
+ lockname
end = time.time(
)+ acquire_timeout
while time.time(
)< end:
if conn.setnx(lockname, identifier)
: conn.expire(lockname, lock_timeout)
return identifier
elif conn.ttl(lockname)
<0:
conn.expire(lockname, lock_timeout)
time.sleep(
0.001
)return
false
#********* end *********#
計數訊號量
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import uuid
import time
import redis
conn = redis.redis(
)# 獲得計數訊號量
defacquire_semaphore
(semname, limit=
5, timeout=10)
:# 請在下面完成要求的功能
#********* begin *********#
identifier =
str(uuid.uuid4())
now = time.time(
) pipeline = conn.pipeline(
) pipeline.zremrangebyscore(semname,
'-inf'
, now - timeout)
pipeline.zadd(semname, identifier, now)
pipeline.zrank(semname, identifier)
if pipeline.execute()[
-1]< limit:
return identifier
conn.zrem(semname, identifier)
return
none
#********* end *********#
# 釋放計數訊號量
defrelease_semaphore
(semname, identifier)
:# 請在下面完成要求的功能
#********* begin *********#
return conn.zrem(semname, identifier)
#********* end *********#
公平訊號量
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import uuid
import time
import redis
conn = redis.redis(
)# 獲得公平訊號量
defacquire_fair_semaphore
(semname, limit=
5, timeout=10)
:# 請在下面完成要求的功能
#********* begin *********#
identifier =
str(uuid.uuid4())
czset = semname +
':owner'
ctr = semname +
':counter'
now = time.time(
) pipeline = conn.pipeline(
true
) pipeline.zremrangebyscore(semname,
'-inf'
, now - timeout)
pipeline.zinterstore(czset,
) pipeline.incr(ctr)
counter = pipeline.execute()[
-1] pipeline.zadd(semname, identifier, now)
pipeline.zadd(czset, identifier, counter)
pipeline.zrank(czset, identifier)
if pipeline.execute()[
-1]< limit:
return identifier
pipeline.zrem(semname, identifier)
pipeline.zrem(czset, identifier)
pipeline.execute(
)return
none
#********* end *********#
# 釋放公平訊號量
defrelease_fair_semaphore
(semname, identifier)
:# 請在下面完成要求的功能
#********* begin *********#
pipeline = conn.pipeline(
) pipeline.zrem(semname, identifier)
pipeline.zrem(semname +
':owner'
, identifier)
return pipeline.execute()[
0]#********* end *********#
!!!!感謝大家的支援!!!! 訊號量與互斥鎖
訊號量與普通整型變數的區別 訊號量 semaphore 是非負整型變數,除了初始化之外,它只能通過兩個標準原子操作 wait semap signal semap 來進行訪問 操作也被成為pv原語 p 於dutch proberen 測試 v 於 dutch verhogen 增加 而普通整型變數則...
訊號量與互斥鎖
原文 訊號量與普通整型變數的區別 訊號量 semaphore 是非負整型變數,除了初始化之外,它只能通過兩個標準原子操作 wait semap signal semap 來進行訪問 操作也被成為pv原語 p 於dutch proberen 測試 v 於 dutch verhogen 增加 而普通整型...
訊號量與互斥鎖
訊號量與普通整型變數的區別 訊號量 semaphore 是非負整型變數,除了初始化之外,它只能通過兩個標準原子操作 wait semap signal semap 來進行訪問 操作也被成為pv原語 p 於dutch proberen 測試 v 於 dutch verhogen 增加 而普通整型變數則...