分佈式-鎖-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的對應的方法,這裏鎖的機制是多線程的內存共享實現的,十個線程是在同一服務上運行的,同時沒有線程隔離操做,

在實際工做中遇到一個問題,在部署高可用集羣時,每臺服務都有一個定時腳本,須要天天運行,可是天天只但願有一個運行,其餘集羣中的服務發現有一個運行時就放棄運行定時腳本中的任務,這時候該如何實現了,多線程的共享通訊 會給我什麼樣的啓發了?該如何設計一個分佈式鎖了?請看第二節

相關文章
相關標籤/搜索