守護進執行緒,互斥鎖,訊號量,佇列,死鎖遞迴鎖等
阿新 • • 發佈:2019-01-07
守護程序:
迷惑人的例子 主程序程式碼執行完畢,守護程序就會結束from multiprocessing import Process import os,time,random def task(): print('%s is running' %os.getpid()) time.sleep(2) print('%s is done' %os.getpid()) # p = Process(target=time.sleep, args=(3,)) # p.start() if __name__ == '__main__': p=Process(target=task) p.daemon = True #1、必須在p.start()之前 2:守護程序不能開啟子程序 p.start() # p.join() print('主') ''' 舉例說明守護程序的應用場景: 假設有兩個任務要幹,要玩出併發的效果,使用程序的話可以讓主程序 執行一個任務,然後開啟一個子程序執行一個任務。 如果這兩個任務毫無關係,那麼就像上面這麼做就可以 如果主程序的任務在執行完畢後,子程序的任務沒有存在的意義了 那麼該子程序應該在開啟之前就被設定成守護程序 '''
互斥鎖三個例子:from multiprocessing import Process from threading import Thread import time def foo(): print(123) time.sleep(1) print("end123") def bar(): print(456) time.sleep(3) print("end456") if __name__ == '__main__': p1=Process(target=foo) p2 = Process(target=bar) p1.daemon=True p1.start() p2.start() print("main-------") #列印該行則主程序程式碼結束,則守護程序p1應該被終止,可能會有p1任務執行的列印資訊123, 因為主程序列印main----時,p1也執行了,但是隨即被終止
from multiprocessing import Process,Lock import os,time,random # 互斥鎖就是給整序列,比join好點,可以控制鎖的時間。 def task(mutex): mutex.acquire() print('%s print 1'%os.getpid()) time.sleep(random.randint(1,2)) print('%s print 2' % os.getpid()) time.sleep(random.randint(1, 2)) print('%s print 3' % os.getpid()) time.sleep(random.randint(1, 2)) mutex.release() if __name__ == '__main__': mutex = Lock() p1 = Process(target=task,args=(mutex,)) p2 = Process(target=task,args=(mutex,)) p3 = Process(target=task,args=(mutex,)) p1.start() p2.start() p3.start() ########################################################## from multiprocessing import Process,Lock import os,time,random,json def search(): with open('db.txt',encoding='utf-8') as f: dic=json.load(f) print('%s 剩餘票數 %s'%(os.getpid(),dic['count'])) def get(): with open('db.txt',encoding='utf-8') as read_f: dic = json.load(read_f) if dic['count'] > 0: dic['count'] -= 1 time.sleep(random.randint(1,3)) with open('db.txt','w',encoding='utf-8')as write_f: json.dump(dic,write_f) print('%s 搶票成功'%os.getpid()) def task(mutex): search() mutex.acquire() get() mutex.release() if __name__ == '__main__': mutex = Lock() for i in range(20): p = Process(target=task,args=(mutex,)) p.start() ######################################################## from threading import Thread,Lock import time n = 100 def task(mutex): global n with mutex: ### 相當於 那 兩行程式碼 temp = n time.sleep(0.01) n = temp-1 if __name__ == '__main__': mutex = Lock() t_l = [] for i in range(100): t = Thread(target=task,args=(mutex,)) ### t = Thread(target=task) # 因為是執行緒資源共享,所以不用傳參args=(mutex,) t_l.append(t) t.start() for i in t_l: i.join() print(n) ############ 0
訊號量:
from multiprocessing import Process,Semaphore
# from threading import Thread,Semaphore
import time,random,os
def task(sm):
with sm:
print('%s 上廁所' %os.getpid())
time.sleep(random.randint(1,3))
if __name__ == '__main__':
sm=Semaphore(3)
for i in range(10):
p=Process(target=task,args=(sm,))
p.start()
==============================================================================================================================ipc機制 : 程序之間通訊,指的是用記憶體空間共享,來實現程序之間通訊: ①管道 ②佇列 frommultiprocessingimportQueue#程序佇列
q=Queue(3)
若 定義為3,則放3個拿3個,超出則程序結束不了,一直等著。
q.put({'a':1})
q.put('xxxxx')
q.put(3)
q.put(4)
print(q.get())
print(q.get())
print(q.get())
print(q.get())
importqueue#執行緒佇列
佇列:先進先出
q=queue.Queue(3)
q.put({'a':1})
q.put('xxxxx')
q.put(3)
q.put(4)
print(q.get())
print(q.get())
print(q.get())
print(q.get())
優先順序佇列:數字越小優先順序越高
q=queue.PriorityQueue(3)
q.put((10,{'a':1}))
q.put((-1,'xxxxx'))
q.put((0,3))
# q.put(4)
print(q.get())
print(q.get())
print(q.get())
print(q.get())
堆疊:先進後出
q=queue.LifoQueue(3)
q.put({'a':1})
q.put('xxxxx')
q.put(3)
# q.put(4)
print(q.get())
print(q.get())
print(q.get())
print(q.get())
死鎖/遞迴鎖
from threading import Thread,Lock,RLock # RLock 就是說可以多次拿鎖。
import time
# mutexA=mutexB=Lock()
mutexA=mutexB=RLock()
###兩個鎖的時候會出現死鎖,一個拿到鎖卻沒釋放
class MyThread(Thread):
def run(self):
self.f1()
self.f2()
def f1(self):
mutexA.acquire()
print('%s 拿到A鎖' %self.name)
mutexB.acquire()
print('%s 拿到B鎖' %self.name)
mutexB.release()
mutexA.release()
def f2(self):
mutexB.acquire()
print('%s 拿到B鎖' % self.name)
time.sleep(0.1)
mutexA.acquire()
print('%s 拿到A鎖' % self.name)
mutexA.release()
mutexB.release()
if __name__ == '__main__':
for i in range(10):
t=MyThread()
t.start()
終身美麗 --- 鄭秀文