python------多執行緒(鎖)
阿新 • • 發佈:2018-12-19
一、類式呼叫
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()