1. 程式人生 > >python筆記10-多線程之線程同步(鎖lock)

python筆記10-多線程之線程同步(鎖lock)

pre 創建 函數 必須 col threading code png sta

前言

關於吃火鍋的場景,小夥伴並不陌生,吃火鍋的時候a同學往鍋裏下魚丸,b同學同時去吃掉魚丸,有可能會導致吃到生的魚丸。
為了避免這種情況,在下魚丸的過程中,先鎖定操作,讓吃火鍋的小夥伴停一會,等魚丸熟了再開吃,那麽python如何模擬這種場景呢?

未鎖定

1.如果多個線程同時操作某個數據,會出現不可預料的結果。比如以下場景:當小夥伴a在往火鍋裏面添加魚丸的時候,小夥伴b在同時吃掉魚丸,這很有可能導致剛下鍋的魚丸被夾出來了(沒有熟),或者還沒下鍋,就去夾魚丸(夾不到)。

# coding=utf-8
import threading
import time

def chiHuoGuo(people, do):
    
print("%s 吃火鍋的小夥伴:%s" % (time.ctime(),people)) time.sleep(1) for i in range(3): time.sleep(1) print("%s %s正在 %s 魚丸"% (time.ctime(), people, do)) print("%s 吃火鍋的小夥伴:%s" % (time.ctime(),people)) class myThread (threading.Thread): # 繼承父類threading.Thread def __init__(self, people, name, do):
‘‘‘重寫threading.Thread初始化內容‘‘‘ threading.Thread.__init__(self) self.threadName = name self.people = people self.do = do def run(self): # 把要執行的代碼寫到run函數裏面 線程在創建後會直接運行run函數 ‘‘‘重寫run方法‘‘‘ print("開始線程: " + self.threadName) chiHuoGuo(self.people, self.do)
# 執行任務 print("qq交流群:226296743") print("結束線程: " + self.name) print("yoyo請小夥伴開始吃火鍋:!!!") # 設置線程組 threads = [] # 創建新線程 thread1 = myThread("xiaoming", "Thread-1", "添加") thread2 = myThread("xiaowang", "Thread-2", "吃掉") # 添加到線程組 threads.append(thread1) threads.append(thread2) # 開啟線程 for thread in threads: thread.start() # 阻塞主線程,等子線程結束 for thread in threads: thread.join() time.sleep(0.1) print("退出主線程:吃火鍋結束,結賬走人")

運行結果:

技術分享圖片

線程同步(鎖lock)

1.為了避免以上這種情況發生,就引入鎖的概念,鎖有兩種狀態:鎖定和未鎖定

2.每當一個線程a要訪問共享數據時,必須先獲得鎖定;如果已經有別的線程b獲得鎖定了,那麽就讓線程a暫停,也就是同步阻塞;等到線程b訪問完畢,釋放鎖以後,再讓線程a繼續。

3.用threading.Lock()這個類裏面的兩個方法

  • acquire() 鎖住
  • release() 釋放鎖
# coding=utf-8
import threading
import time

def chiHuoGuo(people, do):
    print("%s 吃火鍋的小夥伴:%s" % (time.ctime(),people))
    time.sleep(1)
    for i in range(3):
        time.sleep(1)
        print("%s %s正在 %s 魚丸"% (time.ctime(), people, do))
    print("%s 吃火鍋的小夥伴:%s" % (time.ctime(),people))


class myThread (threading.Thread):   # 繼承父類threading.Thread

    lock = threading.Lock()  # 線程鎖

    def __init__(self, people, name, do):
        ‘‘‘重寫threading.Thread初始化內容‘‘‘
        threading.Thread.__init__(self)
        self.threadName = name
        self.people = people
        self.do = do

    def run(self):   # 把要執行的代碼寫到run函數裏面 線程在創建後會直接運行run函數
        ‘‘‘重寫run方法‘‘‘
        print("開始線程: " + self.threadName)

        # 執行任務之前鎖定線程
        self.lock.acquire()

        chiHuoGuo(self.people, self.do)     # 執行任務

        # 執行完之後,釋放鎖
        self.lock.release()

        print("qq交流群:226296743")
        print("結束線程: " + self.name)

print("yoyo請小夥伴開始吃火鍋:!!!")

# 設置線程組
threads = []

# 創建新線程
thread1 = myThread("xiaoming", "Thread-1", "添加")
thread2 = myThread("xiaowang", "Thread-2", "吃掉")

# 添加到線程組
threads.append(thread1)
threads.append(thread2)

# 開啟線程
for thread in threads:
    thread.start()

# 阻塞主線程,等子線程結束
for thread in threads:
    thread.join()

time.sleep(0.1)
print("退出主線程:吃火鍋結束,結賬走人")

運行結果:
技術分享圖片

python筆記10-多線程之線程同步(鎖lock)