python3 线程锁

148 阅读3分钟

python3 线程锁

1.场景:4个仓库管理员同时进仓库查看货物

2.实现:

             1.4个仓库管理员线程

            代码:

import time
import uuid
from threading import Thread


# 仓库实体
class Store():

    def __init__(self):
        super(Store, self).__init__()
        # 库存物
        self.StoreContain: [int] = []
        # 初始化库存物
        self.initStoreContain()

    def initStoreContain(self):
        for i in range(0, 500):
            # print(i)
            self.StoreContain.append(i)

    # 获取库存物
    def fetchStoreContain(self) -> int:
        print("获取库存物")
        out = -1
        l = len(self.StoreContain)
        if l > 0:
            index = l - 1
            out = self.StoreContain[index]
        return out

    # 仓库管理员
    def WarehouseKeeper(self):
        threadingId = str(uuid.uuid4())
        print(threadingId)
        while True:
            fetchOut: int = self.fetchStoreContain()
            if fetchOut != -1:
                print(threadingId + "获取库存物:" + str(fetchOut))
                time.sleep(10)

    # 启动仓库管理员线程
    def startWarehouseKeeper(self):

        thread = Thread(target=self.WarehouseKeeper, args={})
        thread.start()


if __name__ == '__main__':
    # 新建仓库实体
    store: Store = Store()

    # 启动4个仓库管理员线程
    for i in range(0, 4):
        store.startWarehouseKeeper()

异常:(不同线程获取到同一个库存物)

    ed07ff42-171a-41ba-a998-78c333325900

    获取库存物

    ed07ff42-171a-41ba-a998-78c333325900获取库存物:499

    e045f384-cc3d-4d85-8e21-24df11138225

    获取库存物

    e045f384-cc3d-4d85-8e21-24df11138225获取库存物:499

    2ccbac1a-651e-4a95-9ecb-8ff71664774f

    获取库存物

    2ccbac1a-651e-4a95-9ecb-8ff71664774f获取库存物:499

    6926264b-c828-4457-a300-73b63ee5239c

    获取库存物

    6926264b-c828-4457-a300-73b63ee5239c获取库存物:499

 如何解决问题: 1.增加锁(找到货物后标记位置) 互斥锁:

import threading
import time
import uuid
from threading import Thread


# 仓库实体
class Store():

    def __init__(self):
        super(Store, self).__init__()
        # 库存物
        self.StoreContain: [int] = []
        # 初始化库存物
        self.lock=threading.Lock()
        self.initStoreContain()

    def initStoreContain(self):
        for i in range(0, 500):
            # print(i)
            self.StoreContain.append(i)

    # 获取库存物
    def fetchStoreContain(self) -> int:
        print("获取库存物")
        out = -1
        #加锁
        self.lock.acquire()
        l = len(self.StoreContain)
        if l > 0:
            index = l - 1
            out = self.StoreContain[index]
        #释放锁
        self.lock.release()
        return out

    # 仓库管理员
    def WarehouseKeeper(self):
        threadingId = str(uuid.uuid4())
        print(threadingId)
        while True:
            fetchOut: int = self.fetchStoreContain()
            if fetchOut != -1:
                print(threadingId + "获取库存物:" + str(fetchOut))
                time.sleep(10)

    # 启动仓库管理员线程
    def startWarehouseKeeper(self):

        thread = Thread(target=self.WarehouseKeeper, args={})
        thread.start()


if __name__ == '__main__':
    # 新建仓库实体
    store: Store = Store()

    # 启动4个仓库管理员线程
    for i in range(0, 4):
        store.startWarehouseKeeper()

2.将拿着货物后去寻找下一件货物 互斥锁

import threading
import time
import uuid
from threading import Thread


# 仓库实体
class Store():

    def __init__(self):
        super(Store, self).__init__()
        # 库存物
        self.StoreContain: [int] = []
        # 初始化库存物
        self.lock=threading.Lock()
        self.initStoreContain()

    def initStoreContain(self):
        for i in range(0, 500):
            # print(i)
            self.StoreContain.append(i)

    # 获取库存物
    def fetchStoreContain(self) -> int:
        print("获取库存物")
        out = -1
        
        l = len(self.StoreContain)
        if l > 0:
            index = l - 1
            out = self.StoreContain[index]
            self.StoreContain.remove(out)

        return out

    # 仓库管理员
    def WarehouseKeeper(self):
        threadingId = str(uuid.uuid4())
        print(threadingId)
        while True:
            fetchOut: int = self.fetchStoreContain()
            if fetchOut != -1:
                print(threadingId + "获取库存物:" + str(fetchOut))
                time.sleep(10)

    # 启动仓库管理员线程
    def startWarehouseKeeper(self):

        thread = Thread(target=self.WarehouseKeeper, args={})
        thread.start()


if __name__ == '__main__':
    # 新建仓库实体
    store: Store = Store()

    # 启动4个仓库管理员线程
    for i in range(0, 4):
        store.startWarehouseKeeper()