Skip to main content

项目描述

  • 一个单机版的redis分布式锁( A single redis distributed lock)

  • 项目使用set命令来加锁

  • 使用lua脚本来释放锁以保证原子性

  • 注意事项,传入的redis连接池需要必须参数一样,同一个redis数据库

  • 当block=False的时候如果没有获得锁则返回一个AcquireFailException异常

  • acquire方法返回True时候则说明获得锁成功

使用方法一

  • 装饰器使用方法

  • 新建一个RedisLock对象.使用RedisLock的lock装饰器来装饰需要保证原子性的函数

  • 注意该函数不能是阻塞的

  • import threading
    import redis
    
    from safe_redis_lock import RedisLock
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379, password='lyc', db=0)
    
    conn = redis.Redis(connection_pool=pool)
    
    conn.set('producer', 10000)
    redis_lock_ = RedisLock(lock_timeout=5, pool=pool, block=True)
    
    
    @redis_lock_.lock
    def consumer_pp(conn):
        num = int(conn.get('producer'))
        if num == 0:
            return True
        else:
            print(f'we consumer one left --> {num}')
            conn.set('producer', num - 1)
    
    
    def consumer():
        pool = redis.ConnectionPool(host='127.0.0.1', port=6379, password='lyc', db=0)
        while True:
            conn = redis.Redis(connection_pool=pool)
            if consumer_pp(conn):
                break
    
    
    def consumer_thread():
        from threading import Thread
        for i in range(20):
            Thread(target=consumer).start()
    
    
    consumer_thread()

使用方法二:

from safe_redis_lock import RedisLock,AcquireFailException

import redis
import threading
import os
pool = redis.ConnectionPool(host='127.0.0.1', port=6379, password='lyc', db=0)

conn = redis.Redis(connection_pool=pool)

conn.set('producer', 10000)
redis_lock_ = RedisLock(lock_timeout=5, pool=pool, block=True)


def consumer_pp(conn):
    num = int(conn.get('producer'))
    if num == 0:
        return True
    else:
        print(f'we consumer one left --> {num}')
        conn.set('producer', num - 1)


def consumer():
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379, password='lyc', db=0)
    while True:
        conn = redis.Redis(connection_pool=pool)
        value = f'{threading.current_thread().ident}-{os.getpid()}'
        get_lock = False
        try:
            get_lock = redis_lock_.acquire(value = value)
            if get_lock:
                if consumer_pp(conn):
                    break
        except AcquireFailException:
            print('can not get the lock')
        finally:
            if get_lock:
                redis_lock_.release(value)


def consumer_thread():
    from threading import Thread
    for i in range(20):
        Thread(target=consumer).start()


consumer_thread()

Release files for safe_redis_lock 0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for safe_redis_lock 0.1
File Size Uploaded
safe_redis_lock-0.1.tar.gz 3.2 kB Details

Release files / safe_redis_lock-0.1.tar.gz

Download URL safe_redis_lock-0.1.tar.gz
Size 3.2 kB
Tags Source
SHA-256 checksum
How to use checksums
ed9b6545a0ea25762b48ef5a8f9848bd31221f140374aa6441828920c239453a
BLAKE2b-256 checksum
How to use checksums
685b37f23c8537cbba196b3aa33bbd1b692e91435e12ec364aae8798bfe5bfe0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Python-urllib/3.7

Release history Release notifications | RSS feed

This release

0.1 This release

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page