1. 程式人生 > >一個Python多執行緒例項

一個Python多執行緒例項

水果分配的問題:

桌上有一隻盤子,每次只能放入5只水果。爸爸專放蘋果,

媽媽專放橘子,一個兒子專等吃盤子中的橘子,一個女兒專等吃盤子中的蘋果.用P,V操作實現爸爸、媽媽、兒子、女兒程序的同步控制。

貼一下程式碼:

import random

import threading

import time

#建立訊號量threading.Semaphore(value),value是訊號量的初始值。
# acquire() 訊號量-1,當為0時,阻塞當前執行緒。release() 訊號量+1,大於0,喚醒等待此訊號量的一個執行緒。
empty =threading.Semaphore(5)  # 盤子的容量

apple =threading.Semaphore(0)  # 同步蘋果的訊號量

orange =threading.Semaphore(0)  # 同步橘子的訊號量

mutex = threading.Event()  # 表示四個程序互斥的訪問盤子

plate = list()  # 模擬水果盤

lock = threading.Lock()  # plate互斥鎖

mutex.set()  # 設定為True

def father(basket):

    global empty, mutex, lock, apple

    while len(basket) != 0:  # 當蘋果籃子中沒有蘋果,則終止

        # 1.p(empty)

        empty.acquire()  # 將容量empty減去1

        # 2.p(mutex)

        mutex.clear()  # mutex設定為False 其它執行緒將等待

        # 3.put apple

        if lock.acquire():

            temp = basket.pop()

            plate.append(temp)  # 從蘋果籃子裡拿出一個蘋果放入水果盤

            print('->father put anapple({0}) into plate.'.format(temp))

            print('  current plate = ', plate)

            lock.release()

        # 4.v(mutex)

        mutex.set()  # mutex設定為True, 其它執行緒可以使用

        # 5.v(apple)

        apple.release()
        #time.sleep() #執行緒推遲指定的時間執行,單位為秒
        #random.random() #用於生成一個0到1的隨機符點數: 0 <= n < 1.0
        time.sleep(random.random())

def mother(basket):

    global empty, mutex, lock, orange

    while len(basket) != 0:  # 當橘子籃子中沒有橘子,則終止

        # 1.p(empty)

        empty.acquire()  # 將容量empty減去1

        # 2.p(mutex)

        mutex.clear()  # mutex設定為False 其它執行緒將等待

        # 3.put(orange)

        if lock.acquire():

            temp = basket.pop()

            plate.append(temp)

            print('->mother put anorange({0}) into plate.'.format(temp))

            print('  current plate = ', plate)

            lock.release()

        # 4.v(mutex)

        mutex.set()  # mutex設定為True, 其它執行緒可以使用

        # 5.v(orange)

        orange.release()

        time.sleep(random.random())

def son(count):

    global empty, mutex, lock, orange

    for i in range(count):

        # 1.p(orange)

        orange.acquire()  # orange -1

        # 2.p(mutex)

        mutex.clear()  # mutex設定為False 其它執行緒將等待

        # 3.get orange

        if lock.acquire():

            for fruit in plate:

                if fruit.startswith('Orange'):

                    temp = fruit

                    plate.remove(fruit)

                    break

            print('->son take an orange({0})from plate.'.format(temp))

            print('  current plate = ', plate)

            lock.release()

        # 4.v(mutex)

        mutex.set()  # mutex設定為True, 其它執行緒可以使用

        # 5.v(empty)

        empty.release()  # 將empty + 1

        time.sleep(random.random())

def daughter(count):

    global empty, mutex, lock, apple

    for i in range(count):

        # 1.p(apple)

        apple.acquire()  # apple -1

        # 2.p(mutex)

        mutex.clear()  # mutex設定為False 其它執行緒將等待

        # 3.get apple

        if lock.acquire():

            for fruit in plate:

                if fruit.startswith('Apple'):

                    temp = fruit

                    plate.remove(fruit)

                    break

            print('->daughter take anapple({0}) from plate'.format(temp))

            print('  current plate = ', plate)

            lock.release()

        # 4.v(mutex)

        mutex.set()  # mutex設定為True, 其它執行緒可以使用

        # 5.v(empty)

        empty.release()  # 將empty + 1

        time.sleep(random.random())

if __name__ == '__main__':

    # 初始化蘋果和橘子的個數

    apples_basket = ['Apple-A', 'Apple-B','Apple-C', "Apple-D"]  # 模擬蘋果籃子,一共有4個蘋果要放入水果盤

    oranges_basket = ['Orange-A', 'Orange-B','Orange-C']  # 模擬橘子籃子,一共有3個橘子要放入水果盤

    # 建立4個執行緒
    #建立執行緒threading.Thread(target, args), target是要執行的函式,args是函式所需的引數。

    father = threading.Thread(name='Father',target=father, args=(apples_basket, ))  #father 執行緒

    mother = threading.Thread(name='Mother',target=mother, args=(oranges_basket, )) # mother 執行緒

    son = threading.Thread(name='Son',target=son, args=(len(oranges_basket), )) # son 執行緒

    daughter =threading.Thread(name='Daughter', target=daughter, args=(len(apples_basket),))  # daughter 執行緒

    # 啟動執行緒

    daughter.start()

    son.start()

    father.start()

    mother.start()

執行結果: