zoukankan      html  css  js  c++  java
  • 分布式-锁-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的对应的方法,这里锁的机制是多线程的内存共享实现的,十个线程是在同一服务上运行的,同时没有线程隔离操作,

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

    仙衣眠云碧岚袍,一襟潇洒,两袖飘飘。玉墨舒心春酝瓢,行也逍遥,坐也逍遥。
  • 相关阅读:
    windows“画图”工具用法
    数字信号处理的流程
    怎样去掉桌面图标蓝色阴影
    Linux下Wi-Fi配置工具2
    vs2005下面编译自己的luars232.dll
    [spring]03_装配Bean
    [Java IO]02_字节流
    [Java IO]01_File类和RandomAccessFile类
    [Spring]01_环境配置
    Notepad++ 实用技巧
  • 原文地址:https://www.cnblogs.com/max520liuhu/p/12556159.html
Copyright © 2011-2022 走看看