分布式鎖與訊號量

2021-10-10 18:11:38 字數 4765 閱讀 8075

**分布式鎖,是指在分布式的部署環境下,通過鎖機制來讓多客戶端互斥的對共享資源進行訪問。

訊號量的本質也是一種資料操作鎖,它本身不具有資料交換的功能,而是通過控制其他的通訊資源來實現程序間通訊,從而負責資料操作的互斥與同步。

本實訓專案的主要內容是使用 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 增加 而普通整型變數則...