1. 程式人生 > >python------多執行緒(鎖)

python------多執行緒(鎖)

一、類式呼叫

from multiprocessing import Process
import time

class MyProcess(Process):
    def __init__(self):
        super(MyProcess, self).__init__()
        #self.name = name

    def run(self):
        time.sleep(1)
        print ('hello', self.name,time.ctime())


if __name__ == '__main__':
    p_list=[]
    for i in range(3):
        p = MyProcess()
        p.start()
        p_list.append(p)

    for p in p_list:
        p.join()

    print('end')

二、執行緒鎖 在這裡插入圖片描述 一次只允許一個執行緒進入

在Cpython直譯器中,同一個程序下開啟的多執行緒,同一時刻只能有一個執行緒執行,無法利用多核優勢 2.2 互斥鎖

def sub():
    global count
    lock.acquire()  #上鎖,第一個執行緒如果申請到鎖,會在執行公共資料的過程中持續阻塞後續執行緒
                    #即後續第二個或其他執行緒依次來了發現已經被上鎖,只能等待第一個執行緒釋放鎖
                    #當第一個執行緒將鎖釋放,後續的執行緒會進行爭搶

    '''執行緒的公共資料  下'''
    temp=count
    time.sleep(0.001)
    count=temp+1
    '''執行緒的公共資料  上'''

    lock.release()  #釋放鎖
    time.sleep(2)
count=0

l=[]
lock=threading.Lock()   #將鎖內的程式碼序列化
for i in range(100):
    t=threading.Thread(target=sub,args=())
    t.start()
    l.append(t)
for t in l:
    t.join()
print(count)

2.3 遞迴鎖

import threading
import time
def foo():
    rlock.acquire()
    print('func foo ClockA lock')
    rlock.acquire()
    print('func foo ClockB lock')
    rlock.release()
    rlock.release()

def bar():
    rlock.acquire()
    print('func bar ClockB lock')
    time.sleep(2)
    rlock.acquire()
    print('func bar ClockA lock')
    rlock.release()
    rlock.release()


def run():
    foo()
    bar()

rlock=threading.RLock() #RLock本身有一個計數器,如果碰到acquire,那麼計數器+1
                        #如果計數器大於0,那麼其他執行緒無法查收,如果碰到release,計數器-1

for i in range(10):
    t=threading.Thread(target=run,args=())
    t.start()

2.4 訊號量

# 互斥鎖同時只允許一個執行緒更改資料,而Semaphore是同時允許一定數量的執行緒更改資料,比如
# 一個廁所有3個坑,那麼最多隻允許3個人上廁所,後面的人只能等裡面有人出來了才能再進去
 
 
import threading
import time
 
def run(n):
    semaphore.acquire()
    time.sleep(1)
    print("run the thread: %s" %n)
    semaphore.release()
 
 
if __name__ == '__main__':
    num = 0
    semaphore = threading.BoundedSemaphore(3)
    #最多允許3個執行緒同時執行
    for i in range(20):
        t = threading.Thread(target=run,args=[i,])
        t.start()
 
 
while threading.active_count() != 1:
    print(threading.active_count())
    pass
else:
    print("----all threads done----------")
    print(num)

2.5 條件變數

# *-* coding=gb2312 *-*
'''
訊號量semaphore
是一個變數,控制著對公共資源或者臨界區的訪問。訊號量維護著一個計數器,指定可同時訪問資源或者進入臨界區的執行緒數。
每次有一個執行緒獲得訊號量時,計數器-1。若計數器為0,其他執行緒就停止訪問訊號量,直到另一個執行緒釋放訊號量。
'''
import threading
import random
import time
 
class MyThread(threading.Thread):
    availableTables=['A','B','C','D','E']
    
    def __init__(self,threadName,semaphore):
        self.interval =random.randrange(1,6)
        self.semaphore =semaphore
        threading.Thread.__init__(self,name=threadName)
    
    def run(self):
        self.semaphore.acquire()
        #acquire a semaphore
        table = MyThread.availableTables.pop()
        print "%s entered;seated at table %s." %(self.getName(),table)
        time.sleep(self.interval)
        
        #free a table
        print "%s exiting,freeing table %s." %(self.getName(),table)
        MyThread.availableTables.append(table)
        
        self.semaphore.release()
 
mySemaphore = threading.Semaphore(len(MyThread.availableTables))
 
def Test():        
    threads=[]
    
    for i in range(1,10):
        threads.append(MyThread("thread"+str(i),mySemaphore))
    
    for i in range(len(threads)):
        threads[i].start()
 
if __name__ == '__main__':
    Test()

2.6 同步變數 ecent的4個方法:

event.isSet():返回event的狀態值

event.set():將event的狀態值設定為True

event.wait():等待,直到event的值變為True,否則,一直阻塞住

event.clear():將event的值設定為False

import threading
import time
event = threading.Event()#建立了一個event

class boss(threading.Thread):
    def run(self):

        print("開始工作了")
        event.isSet() or event.set()#將event的狀態置為ture,讓worker開始幹活
        time.sleep(4)#在這個時間段,工人們開始幹活
        print('可以下班了')
        event.isSet() or event.set()#將event的狀態置為ture,工人們下班


class worker(threading.Thread):
    def run(self):
        # r.acquire()
        event.wait()#等待boss發指令
        print("不要阿")
        time.sleep(1)#開始幹活
        # r.release()
        event.clear()#將event的狀態置為false
        event.wait()#等待boss的進一步指令
        print("好也,回家吃莽莽")


if __name__ == '__main__':
    p = []

    for i in range(3):
        p.append(worker())

    p.append(boss())
    for i in p:
        i.start()
    # for i in p:
    #     i.join()