pytho---多執行緒(鎖)
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§
for p in p_list:
p.join()
print('end')
複製程式碼
一、類式呼叫
二、執行緒鎖
2.1 全域性直譯器鎖
一次只允許一個執行緒進入
在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()
複製程式碼