1. 程式人生 > >python 多執行緒程式設計

python 多執行緒程式設計

import threading

#當前執行緒   列印執行緒名
t=threading.current_thread()
print(t.name)
#活動執行緒數
print(threading.active_count())
#當前主執行緒
t=threading.main_thread()
print(t.name)

建立可執行執行緒:

例1,

import threading
import time

def main():
    #執行緒物件t1
    t1=threading.Thread(target=thread_body) #執行緒體  name預設
    t1.start()#執行緒啟動
    #執行緒2
    t2 = threading.Thread(target=thread_body)
    t2.start()
def thread_body():
    #當前執行緒物件
    t=threading.current_thread()
    for i in range(5):
        print(i,'次,執行',t.name)
        #當前執行緒休眠1秒,有了休眠  多執行緒才會交替執行
        time.sleep(1)
    print('{}完成'.format(t.name))
if __name__=='__main__':
    main()

結果:

例2:

import threading
import time
class my_thread(threading.Thread):
    def __init__(self,name=None):
        super().__init__(name=name)
    #重寫run()
    def run(self):
        t = threading.current_thread()
        for i in range(5):
            print(i, '次,執行', t.name)
            time.sleep(1)
        print('{}完成'.format(t.name))


def main():
    t1=my_thread()
    t1.start()
    t2=my_thread(name='thread2')
    t2.start()



if __name__=='__main__':
    main()

執行緒管理

 jion等待:

import threading
import time
value=0
def thread_body():
    global value
    print('thread 開始')

    for i in range(2):
        print('迴圈執行')
        value +=1
        time.sleep(1)
    print('thread 結束')
def main():
    t1=threading.Thread(target=thread_body,name='T1')
    t1.start()

    t1.join()    #  等待t1結束,阻塞當前執行緒
    print(value)
    
if __name__=='__main__':
    main()

結果:

執行緒停止:

import threading
import time
value=True
def thread_body():
    global value
    print('thread 開始')

    while value:
        print('yunxing')
        time.sleep(3)
    print('thread 結束')
def main():
    global value
    t1=threading.Thread(target=thread_body,name='T1')
    t1.start()
    a=int(input('輸入數字  按回車 結束程序'))
    if a>=0:
        value=False

if __name__=='__main__':
    main()

臨界資源問題

出現的問題如下:

import threading
import time

class ticket():
    def __init__(self,count):
        self.ticket_count=count
    def get_count(self):
        return self.ticket_count
    def sell(self):
        #模擬等待使用者付款
        time.sleep(1)
        print('{}號票已出'.format(self.ticket_count))
        self.ticket_count -=1

t=ticket(5) #例項化



def thread_body1():
    global t
    print('t1 開始')

    while True:
        curr_tick = t.get_count()
        if curr_tick>0:
            t.sell()
        else:
            break
    print('t1 結束')
def thread_body2():
    print('t2 開始')
    global t
    curr_tick = t.get_count()
    while True:
        curr_tick = t.get_count()
        if curr_tick > 0:
            t.sell()
        else:
            break
    print('t2 結束')


def main():
    t1=threading.Thread(target=thread_body1,name='T1')
    t1.start()
    t2 = threading.Thread(target=thread_body2, name='T1')
    t2.start()

if __name__=='__main__':
    main()

同時使用了3號票的資料

要使用   多執行緒同步

import threading
import time

class ticket():
    def __init__(self,count):
        self.ticket_count=count
    def get_count(self):
        return self.ticket_count
    def sell(self):
        #模擬等待使用者付款
        time.sleep(1)
        print(threading.current_thread().name)
        print('{}號票已出'.format(self.ticket_count))

        self.ticket_count -=1

t=ticket(10) #例項化


# 建立lock
lock=threading.Lock()


def thread_body1():
    global t,lock

    print('t1 開始')

    while True:
        lock.acquire()#上鎖
        curr_tick = t.get_count()
        if curr_tick>0:
            t.sell()

        else:
            lock.release()#解鎖
            break
        lock.release()#解鎖
        time.sleep(1)  #做到交替執行
    print('t1 結束')
def thread_body2():
    print('t2 開始')
    global t,lock

    while True:
        lock.acquire()
        curr_tick = t.get_count()
        if curr_tick > 0:
            t.sell()

        else:
            lock.release()#解鎖
            break
        lock.release()#解鎖
        time.sleep(3)#做到交替執行
    print('t2 結束')


def main():
    t1=threading.Thread(target=thread_body1,)
    t1.start()
    t2 = threading.Thread(target=thread_body2, )
    t2.start()

if __name__=='__main__':
    main()

結果:

執行緒間通訊問題

堆疊 例子:

1.使用Condition()

import threading
import time

#!!!!!!建立條件變數!!!!!!!!!!
condition=threading.Condition()

class Stack:
    def __init__(self):
        #棧頂指標
        self.point=0
        #5個位置的棧
        self.data=[-1,-1,-1,-1,-1]
    #壓棧
    def push(self,c):
        global condition
        condition.acquire()#加鎖
        while self.point==len(self.data):  #棧滿
            #等待其他執行緒  出棧
            condition.wait()
            #通知其他執行緒
            condition.notify()

        self.data[self.point]=c
        self.point +=1

        condition.release()#解鎖
    #出棧
    def pop(self):
        global condition
        condition.acquire()
        # 堆疊無資料,不能出棧
        while self.point == 0:
            # 等待其他執行緒把資料壓棧
            condition.wait()
            # 通知其他執行緒壓棧
            condition.notify()

        self.point -=1
        out=self.data[self.point]
        condition.release()
        return out

S=Stack()
#新增執行緒體
def t_add():
    global S
    for i in range(9):
        S.push(i)
        print('壓入',i)
        time.sleep(1)
def t_out():
    global S
    for i in range(9):
        x=S.pop()
        print('彈出',x)
        time.sleep(1)


def main():
    producer = threading.Thread(target=t_add)
    producer.start()
    consumer = threading.Thread(target=t_out)
    consumer.start()


if __name__=='__main__':
     main()

2.使用event()

import threading
import time

event=threading.Event()

class Stack:
    def __init__(self):
        #棧頂指標
        self.point=0
        #5個位置的棧
        self.data=[-1,-1,-1,-1,-1]
    #壓棧
    def push(self,c):
        global event
        while self.point==len(self.data):  #棧滿
            #等待其他執行緒  出棧
            event.wait()
            #通知其他執行緒
        event.set()

        self.data[self.point]=c
        self.point +=1

    #出棧
    def pop(self):
        global event
        # 堆疊無資料,不能出棧
        while self.point == 0:
            # 等待其他執行緒把資料壓棧
            event.wait()
            # 通知其他執行緒壓棧
        event.set()

        self.point -=1
        out=self.data[self.point]
        return out

S=Stack()
#新增執行緒體
def t_add():
    global S
    for i in range(9):
        S.push(i)
        print('壓入',i)
        time.sleep(1)
def t_out():
    global S
    for i in range(9):
        x=S.pop()
        print('彈出',x)
        time.sleep(1)


def main():
    producer = threading.Thread(target=t_add)
    producer.start()
    consumer = threading.Thread(target=t_out)
    consumer.start()


if __name__=='__main__':
     main()