日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

互斥锁、共享内存方式以及生产者消费者模型

發布時間:2025/3/19 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 互斥锁、共享内存方式以及生产者消费者模型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

守護進程

1、守護進程的概念

  進程指的是一個正在運行的程序,守護進程也是一個普通進程

  意思就是一個進程可以守護另一個進程

import time from multiprocessing import Processdef task():print("子進程 走起!!!")time.sleep(5)print("子進程 掛掉了")if __name__ == '__main__':print("主進程 走起!!!")p = Process(target=task)p.daemon = True # 將子進程設置為守護進程 p.start()time.sleep(3)print("主進程 掛掉了") # --1)如果設置為守護進程,那么主進程一旦結束,那么子進程立馬也結束(代碼終止執行) # --2)如果沒有設置為守護進程,那么主進程結束執行完代碼之后,子進程還會繼續執行子進程里面的代碼

2、結論

  如果a 是 b 的守護進程,那么 b 就是被守護的進程, b要是(代碼運行完畢)死? ,a也會跟著死

  守護進程在主進程代碼運行結束之后就死了

3、使用場景

  父進程交給了子進程一個任務,任務還沒有完成父進程就結束了,子進程就沒有繼續執行的意義了

  例如qq接到一個視頻文件,于是開啟了一個子進程來下載,如果中途退出了qq,下載任務就沒必要繼續執行了

互斥鎖(重點)

為什么需要互斥鎖

  當我們同時開啟幾個子進程的時候,而這幾個子進程又要同時操作一個資源(文件或者控制臺),

  將會導致數據的錯亂問題(誰先搶到誰打印,數據混亂看不懂)

解決方案1:

  加join? ? (就是每開一個子進程,就加一個join,限制后面的子進程不能開啟)

  弊端:

    --1、把原本并發的任務變成了串行,避免了數據錯亂問題,但是效率降低了,

      而且是執行完第一個子進程才開啟第二個子進程,都放在主程序也是同樣效果,沒必要開子進程

    --2、原本多個進程之間公平競爭,join執行的順序是定死的,不合理

解決法案2:

  給公共資源加鎖(互斥鎖)

    互斥鎖,字面理解就是互相排斥的鎖,在程序中指的是,如果這個資源已經被鎖住了,其他進程就無法使用

    需要強調的是:鎖,并不是真正的把資源鎖起來,只是在代碼里加限制,限制你的代碼不能執行

import time,random from multiprocessing import Process,Lockdef task1(lock):lock.acquire() # 上鎖print('任務一 走起')time.sleep(random.randint(0,2))print('任務一 結束')lock.release() # 解鎖def task2(lock):lock.acquire()print('任務二 走起')time.sleep(random.randint(0,2))print('任務二 結束')lock.release()def task3(lock):lock.acquire()print('任務三 走起')time.sleep(random.randint(0,2))print('任務三 結束')lock.release()if __name__ == '__main__':lock = Lock()p1 = Process(target=task1,args=(lock,))p2 = Process(target=task2,args=(lock,))p3 = Process(target=task3,args=(lock,))p1.start()p2.start()p3.start()

  注意:

    --1、不要對同一代碼執行多次acquire,會鎖死程序無法執行,一次acquire必須對應一次release

      ? (一次加鎖相當于在代碼做一次判斷,判斷成功改狀態,再加鎖又相當于做一次判斷,判斷就會失敗,鎖死)

    --2、想要保證數據安全,必須保證所有進程使用同一把鎖

       (如果每個進程拿到的鎖都不一樣,那么判斷的條件就不會同步)

鎖和join的區別

  1、join是固定了執行順序,會造成父進程等待子進程

    鎖依然是公平競爭,誰先搶到誰先執行,父進程也可以執行其他任務

  2、最主要的區別:

    join是把進程的所有任務全部串行

    鎖可以所以任意代碼,一行也可以,可以自己調整粒度? 粒度(指的是被鎖住代碼的大小,越小效率越快)

IPC

  IPC就是進程間通訊,通訊指的是交換數據

  進程之間的內存是相互隔離的,當一個進程想要把數據給另外一個進程,就需要考慮到IPC

IPC方式:

  管道:只能單向通訊(一邊讀,一邊寫),數據都是二進制

  文件:在硬盤上創建共享文件

      優點:硬盤的空間大,所以共享的數據量幾乎沒有限制

      缺點:硬盤讀取速度慢

  socket:編程復雜度高

  共享內存: 必須由操作系統來分配? ? ?(必須掌握)

    優點:速度快

    缺點:數據量不能太大

共享內存的方式

1、Manager類

  Manager提供了很多數據結構,如list,dict等等(可以在源碼中看到)

  Manager所創建出來的數據結構,具備進程間共享的特點

from multiprocessing import Manager,Process,Lock import timedef task(dic,lock):lock.acquire() # 這里如果不加鎖的話,可能出現多個進程剛取出來的值都是100,然后修改完都是99nums = dic["nums"]# time.sleep(2) # 所有進程拿到100睡2秒,最后修改的數據就是99dic["nums"] = nums - 1lock.release() if __name__ == '__main__':lock = Lock()m = Manager() # 創建一個manager對象dic = m.dict({"nums":100}) # 括號里需要的是一個映射關系,幫我們生成一個進程間共享的字典for i in range(5):p = Process(target=task,args=(dic,lock))p.start()time.sleep(10)print(dic["nums"])

需要注意的是:manager創建的一些數據結構是不帶鎖的,可能會出現同時修改一個數據的情況,會出問題,不推薦使用、

2、Queue隊列 幫我們處理了鎖的問題 (重點)

  隊列是一種特殊的數據結構,先存儲的先取出,就像排隊,先進的先出

  相反的就是堆棧,先存取的后取出,就像把衣服疊進箱子,取的時候先取后疊進去的

  函數嵌套調用時,執行的順序也是先進后出,也稱之為函數棧

from multiprocessing import Queueq = Queue(maxsize=3) # 創建一個隊列,里面的參數表示的是隊列的容量,如果不寫默認無限大# 存數據 q.put() 放進去 q.put("a") q.put("b") q.put("c") # q.put("d") # 如果隊列里面已經滿了,你還繼續往里放,他就會進入阻塞狀態,一直等到隊列有空位置把數據放進去# 取數據 q.get() 拿出來 print(q.get()) print(q.get()) print(q.get()) # print(q.get()) # 同樣的,如果隊列里面已經空了,你還繼續取,它也會進入阻塞狀態,一直等到隊列里有數據然后取出來 q.get(block=True,timeout=2) # 里面block參數表示的是是否阻塞,默認True(阻塞),當設置為False時,并且隊列為空時會立馬拋出異常 q.put("aaa",block=True,timeout=2) # 里面block參數表示的是是否阻塞,默認True(阻塞),當設置為False時,并且隊列為滿時會立馬拋出異常 # timeout 表示的時阻塞的超時時間,超過時間還是沒有位置或著空的話就會拋出異常

生產者消費者模型 (重點)

1、概念

  模型? 就是解決某個問題的套路

  產生數據的一方稱之為生產者

  處理數據的一方稱之為消費者

  例如:飯店廚師就是生產者,吃飯的人就是消費者

2、生產者和消費者產生的問題

  生產者和消費者,處理速度不平衡,一方快一方慢,導致一方需要等待另一方再能接著往下執行

3、生產者消費者模型解決這個問題的思路

  原本,雙方是耦合在一起,消費者必須等待生產著生成完畢再開始處理,反過來,

  如果消費者消費速度太慢,生產著必須等待其處理完畢才能開始生成下一個數據

4、解決的方案

  將雙方分開來,一方專門,負責生產,一方專門負責處理

  一樣一來,雙方的數據就不能直接交互了,雙方需要共同的容器

  這樣就解決了雙方能力不平衡的問題,做的快的一方可以繼續做,不需要等待另一方,提高了整體的運行效率

from multiprocessing import Process,Queue import time,random def eater(q):for i in range(5):time.sleep(random.randint(0, 2))food = q.get()print("%s吃完了"%food)def cooker(q):for i in ["包子","骨頭","","","刀子"]:time.sleep(random.randint(0, 2))q.put(i)print("%s做好了"%i)if __name__ == '__main__':q = Queue()cp = Process(target=cooker,args=(q,))ep = Process(target=eater,args=(q,))cp.start()ep.start()

轉載于:https://www.cnblogs.com/hesujian/p/10968848.html

總結

以上是生活随笔為你收集整理的互斥锁、共享内存方式以及生产者消费者模型的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。