分布式-锁-1.1 多线程锁无法满足的场景

针对远程某一个数值进行计算 希望每次加1,批量加十次,最终结果比初始增加十

不加锁的代码 不满足要求

import threading, time, redis
from redis import StrictRedis


def increase_num(redis_conn, key):
    value = redis_conn.get(key)  # 获取数据
    time.sleep(0.1)
    if value:
        value = int(value) + 1
    else:
        value = 0
    redis_conn.set(key, value)
    thread_name = threading.current_thread().name
    print(thread_name, value)


##主程序
if __name__ == "__main__":
    pool = redis.ConnectionPool(host='192.168.200.136', port=6379, db=8)
    redis_pool = StrictRedis(connection_pool=pool)
    lock_key = 'test_key'
    thread_count = 10
    for i in range(thread_count):
        thread = threading.Thread(target=increase_num, args=(redis_pool, lock_key))
        thread.start()

#结果 是几乎同时操作
Thread-4 24
Thread-2 24
Thread-1 24
Thread-6 24
Thread-5 24
Thread-3 24
Thread-10 24
Thread-9 24
Thread-7 24
Thread-8 24


解决方法: 利用多线程共享锁的机制,针对操作对象加锁

import threading, time, redis
from redis import StrictRedis


def increase_num(redis_conn, key):
    lock.acquire()
    try:
        value = redis_conn.get(key)  # 获取数据
        time.sleep(0.1)
        if value:
            value = int(value) + 1
        else:
            value = 0
        redis_conn.set(key, value)
        thread_name = threading.current_thread().name
        print(thread_name, value)
    except Exception as e:
        pass
    finally:
        lock.release()

##主程序
if __name__ == "__main__":
    pool = redis.ConnectionPool(host='192.168.200.136', port=6379, db=8)
    redis_pool = StrictRedis(connection_pool=pool)
    lock_key = 'test_key'
    lock = threading.Lock()
    thread_count = 10
    for i in range(thread_count):
        thread = threading.Thread(target=increase_num, args=(redis_pool, lock_key))
        thread.start()

#结果 符合预期
Thread-1 25
Thread-2 26
Thread-3 27
Thread-4 28
Thread-5 29
Thread-6 30
Thread-7 31
Thread-8 32
Thread-9 33
Thread-10 34

这里针对redis中的某个key加一的操作只是用来举例子,针对redis操作可以用redis的对应的方法,这里锁的机制是多线程的内存共享实现的,十个线程是在同一服务上运行的,同时没有线程隔离操作,

在实际工作中遇到一个问题,在部署高可用集群时,每台服务都有一个定时脚本,需要每天运行,但是每天只希望有一个运行,其他集群中的服务发现有一个运行时就放弃运行定时脚本中的任务,这时候该如何实现了,多线程的共享通信 会给我什么样的启发了?该如何设计一个分布式锁了?请看第二节

猜你喜欢

转载自www.cnblogs.com/max520liuhu/p/12556159.html