day 34 守护线程守护进程 互斥锁线程 信号量 生产者消费者
今日內容
1、守護進程vs 守護線程(*)
2、互斥鎖(**)
3、信號量(**)
4、生產者消費者模型(*****)
5、GIL(什么時候用進程,什么時候用線程)(*****)
?
一、守護進程和守護線程
1、守護進程 ?(分出去的進程設置成守護進程)
守護進程不能開啟子進程
#守護進程 from multiprocessing import Process import os,time,randomdef 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()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也執行了,但是隨即被終止 迷惑人的例子
? 總結 ?:主進程運行完畢,守護進程也會隨之結束
2、守護線程?
? 一個進程開啟了多個線程
?(1)守護線程能開啟子線程
#守護線程:等到該進程內所有非守護線程都運行完才死掉 from multiprocessing import Process from threading import Thread import os,time,randomdef task():t=Thread(target=time.sleep,args=(3,))t.start()print("%s is running"% os.getpid())time.sleep(2)print("%s is done"%os.getpid()) if __name__=="__main__":t=Thread(target=task)t.daemon=True #1、必須在t.start()之前2:守護線程可以開啟子線程 t.start()t.join()print("主") 守護線程(2)迷惑人的例子 ?————守護線程
? ? ? 其中非守護線程還沒有結束(開啟線程的目的是為了執行完畢函數)
#迷惑人的例子:守護線程 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(2)print("end456")if __name__=="__main__":t1=Thread(target=foo)t2=Thread(target=bar)t1.daemon=Truet1.start()t2.start()print("main_____") # 123 # 456 # main_____ # end123 # end456 迷惑人的例子——守護線程?
3、總結:
? ? 為什么守護進程內不讓開啟子進程?
主進程結束之后守護線程就會死掉(在這個進程中所有的非守護線程都運行完)
主線程什么時候結束?
主進程死掉(所有的線程結束后) 接著守護進程就會死掉
?二、互斥鎖
1、互斥鎖進程
from multiprocessing import Process,Lock import os,time,randomdef task():print("%s print 1"%os.getpid())time.sleep(random.randint(1,3))print("%s print 2"%os.getpid())time.sleep(random.randint(1, 3))print("%s print 3" % os.getpid())if __name__=="__main__":p1=Process(target=task)p2=Process(target=task)p3=Process(target=task)p1.start()p1.join()p2.start()p2.join()p3.start()p3.join() 1、low的做法 from multiprocessing import Process,Lock import os,time,randomdef task(mutex):mutex.acquire()print("%s print 1"%os.getpid())time.sleep(random.randint(1,3))print("%s print 2"%os.getpid())time.sleep(random.randint(1, 3))print("%s print 3" % os.getpid())mutex.release() if __name__=="__main__":# p1=Process(target=task)# p2=Process(target=task)# p3=Process(target=task)# p1.start()# p1.join()# p2.start()# p2.join()# p3.start()# p3.join()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() 2、改進的互斥鎖方法2、模擬搶票的例子
from multiprocessing import Process,Lock import json import os,time,randomdef 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"]-=1time.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__":# for i in range(20):# p=Process(target=task)# p.start()# p.join()mutex=Lock()for i in range(20):p=Process(target=task,args=(mutex,))p.start()p.join() 模擬搶票的例子3、線程互斥鎖
# 線程互斥鎖 from threading import Thread,Lock import time n=100 def task():global nwith mutex:temp=ntime.sleep(0.1)n=temp-1 if __name__=="__main__":mutex=Lock()t_1=[]for i in range(100):t=Thread(target=task)t_1.append(t)t.start()for t in t_1:t.join()print(n) 線程互斥鎖三、信號量(和進程池不一樣)
例子:搶公共廁所(假如進去10個人,十把鑰匙,結束一個就釋放鑰匙,然后進去一個)
1、進程的信號量:
from multiprocessing import Process,Semaphore # from threading import Thread,Semaphore import time,random,osdef 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):for i in range(10):p=Process(target=task,args=(sm,))p.start() 信號量2、小心鎖與鎖之間的嵌套
(1)管道和隊列都是用的內存的空間
(2)隊列是基于管道加鎖實現的
(3)如果對管道感興趣就看博客 ? 隊列推薦使用
3、 ?進程Queue 和線程Queue?
不能直接放視頻,應該直接放路徑或者是鏈接
(1)
from multiprocessing import Queue #進程隊列# import queue #線程隊列 q=Queue(3)q.put({"a":1}) q.put("xxxxx") q.put(2) q.put(4)print(q.get()) print(q.get()) print(q.get()) print(q.get())(2)隊列的功能————先進先出
from multiprocessing import Queue #進程隊列 import queue #線程隊列 q=queue.Queue(3) q.put({"a":1}) q.put("xxxxx") q.put(2) q.put(4)print(q.get()) print(q.get()) print(q.get()) print(q.get()) 隊列 # 優先級隊列 from multiprocessing import Queue #進程隊列 import queue #線程隊列 q=queue.PriorityQueue(3) q.put((10,{"a":1})) q.put((-1,"xxxxx")) q.put((0,2))print(q.get()) print(q.get()) print(q.get()) # (-1, 'xxxxx') # (0, 2) # (10, {'a': 1}) 優先級隊列(3)堆棧————后進先出
# 堆棧 from multiprocessing import Queue #進程隊列 import queue #線程隊列 q=queue.LifoQueue(3) q.put({"a":1}) q.put("xxxxx") q.put(2)print(q.get()) print(q.get()) print(q.get()) print(q.get()) # 2 # xxxxx # {'a': 1} 堆棧?四、生產者和消費者模型
模型指的概念
? ? 生產者消費者可以實現程序的解耦 ?
from multiprocessing import Process,Queue import time,random,osdef producer(q):for i in range(10):res="包子 %s"%itime.sleep((random.randint(1,3)))q.put(res)print("%s生產了%s"%(os.getpid(),res))def consumer(q):while True:res=q.get()print("%s 吃 %s"%(os.getpid(),res))time.sleep((random.randint(2,3)))if __name__=="__main__":q=Queue()p=Process(target=producer,args=(q,))c=Process(target=consumer,args=(q,))p.start()c.start()print("主")from multiprocessing import Process,Queue import time,random,os def procducer(q):for i in range(10):res="包子%s"%itime.sleep(0.5)q.put(res)print("%s生產了%s"%(os.getpid(),res)) 生產者和消費者 1?
?線程要不要用生產者消費者模型
? ?也要用隊列來實現
from multiprocessing import Process,Queue import time,random,os def procducer(q):for i in range(10):res="包子%s"%itime.sleep(0.5)q.put(res)print("%s生產了%s"%(os.getpid(),res))def consumer(q):while True:res=q.get()if res is None:breakprint("%s 吃 %s"%(os.getpid(),res))time.sleep(random.randint(2,3))if __name__=="__main__":q=Queue()p=Process(target=procducer,args=(q,))c=Process(target=consumer,args=(q,))p.start()c.start()p.join()q.put(None)print("主") 生產者消費者模型?
轉載于:https://www.cnblogs.com/number1994/p/8185408.html
總結
以上是生活随笔為你收集整理的day 34 守护线程守护进程 互斥锁线程 信号量 生产者消费者的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Axure原型设计相关:Axure RP
- 下一篇: MES系统是什么?MES系统的主要功能是