標籤:range code 處理序間通訊 down class /usr 建立 互斥 json
1、開啟進程的兩種方式
方式一
def task(name): print(" %s start..." % name)if __name__ == ‘__main__‘: p = Process(target=task, args=("sb",)) p.start()
方式二
class Piao(Process): def __init__(self, name): super().__init__() self.name = name def run(self): print(‘%s start..‘ % self.name)if __name__ == ‘__main__‘: p1 = Piao("sb") p1.start()
terminate和is_alive
from multiprocessing import Processimport timedef task(name): time.sleep(1) print("%s done.." % name) if __name__ == ‘__main__‘: p1 = Process(target=task, args=("sb",)) p1.start() p1.terminate() # 發送關閉進程命令 print(p1.is_alive()) # 查看進程是否活動 # True print("主") time.sleep(1)
name與pid
from multiprocessing import Processimport osdef task(name): print("%s start..." % name) if __name__ == ‘__main__‘: p = Process(target=task, args=("sb",), name="子進程1") # 可以用關鍵參數來指定進程名 p.start() print(p.name, p.pid, os.getppid()) # p.ppid 報錯 print(os.getpid()) # p.pid==os.getpid()
守護進程
一、守護進程在主進程執行結束終止
二、守護進程內無法開啟子進程。
from multiprocessing import Processimport timedef 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-------")
互斥鎖
前戲:進程之間資料不共用,但是共用同一套檔案系統,所以訪問同一個檔案,或者開啟同一個列印終端,共用帶來競爭。
互斥鎖:互斥鎖的意思就是互斥。保證了資料安全不錯亂。
from multiprocessing import Processfrom multiprocessing import Lockimport timedef task(name, mutex): mutex.acquire() print("%s 1" % name) time.sleep(1) print("%s 2" % name) mutex.release() if __name__ == ‘__main__‘: mutex = Lock() for i in range(2): p = Process(target=task, args=("進程%s" % i, mutex)) p.start()
互斥鎖和join的區別
互斥鎖是讓加鎖部分變成串性,join是讓整段代碼都變成串列。
#!/usr/bin/env python# -*- coding: utf-8 -*-# __author__:JasonLINfrom multiprocessing import Process, Lockimport timeimport jsondef search(name): time.sleep(1) data = json.load(open("data.txt", "r")) print("<%s>剩餘票數[%s]" % (name, data["count"])) def buy(name): data = json.load(open("data.txt", "r")) if int(data["count"]) > 0: data["count"] -= 1 time.sleep(2) json.dump(data, open("data.txt", "w")) print("%s 購票成功" % name) def task(name, mutex): search(name) mutex.acquire() buy(name) mutex.release() if __name__ == ‘__main__‘: mutex = Lock() for i in range(10): p = Process(target=task, args=("路人%s" % i, mutex)) p.start()
join方法,search和buy都變成串列,效率更低。
from multiprocessing import Processimport timeimport jsondef search(name): data = json.load(open("data.txt", "r")) time.sleep(1) print("<%s>剩餘票數[%s]" % (name, data["count"]))def buy(name): data = json.load(open("data.txt", "r")) if int(data["count"]) > 0: data["count"] -= 1 time.sleep(2) json.dump(data, open("data.txt", "w")) print("%s 購票成功" % name) def task(name): search(name) buy(name)if __name__ == ‘__main__‘: for i in range(10): p = Process(target=task, args=("路人%s" % i,)) p.start() p.join()
隊列
進程彼此之間互相隔離,要實現處理序間通訊(IPC),multiprocessing模組支援兩種形式:隊列和管道,這兩種方式都是使用訊息傳遞的。
建立隊列的類(底層就是以管道和鎖定的方式實現)
Queue([maxsize]):建立共用的進程隊列,Queue是多進程安全的隊列,可以使用Queue實現多進程之間的資料傳遞Queue([maxsize]):是隊列中允許最大項數,省略則無大小限制q.put方法用以插入資料到隊列中。q.get方法可以從隊列讀取並且刪除一個元素。
代碼執行個體
from multiprocessing import Process,Queueq=Queue(3)#put ,get ,put_nowait,get_nowait,full,emptyq.put(1)q.put(2)q.put(3)print(q.full()) #滿了# q.put(4) #再放就阻塞住了print(q.get())print(q.get())print(q.get())print(q.empty()) #空了# print(q.get()) #再取就阻塞住了
生產者消費者模型
為什麼要使用生產者消費者模型?
生產者指的是生產資料的任務,消費者指的是處理資料的任務,在並發編程中,如果生產者處理速度很快,而消費者處理速度很慢,那麼生產者就必須等待消費者處理完,才能繼續生產資料。同樣的道理,如果消費者的處理能力大於生產者,那麼消費者就必須等待生產者。為瞭解決這個問題於是引入了生產者和消費者模式。
什麼是生產者和消費者模式?
生產者消費者模式是通過一個容器來解決生產者和消費者的強耦合問題。生產者和消費者彼此之間不直接通訊,而通過阻塞隊列來進行通訊。
這個阻塞隊列就是用來給生產者和消費者解耦的
轉自:
https://www.luffycity.com/python-book/di-7-zhang-bing-fa-bian-cheng/72-bing-fa-bian-cheng-zhi-duo-jin-cheng/727-sheng-chan-zhe-xiao-fei-zhe-mo-xing.html
from multiprocessing import Process, Queueimport timeimport randomdef producer(q): for i in range(3): res = "包子%s" % i time.sleep(0.5) print("生產了%s" % res) q.put(res) def consume(q): while True: res = q.get() if not res: break time.sleep(random.randint(1, 3)) print("吃了%s" % res) if __name__ == ‘__main__‘: q = Queue() p1 = Process(target=producer, args=(q,)) p2 = Process(target=producer, args=(q,)) p3 = Process(target=producer, args=(q,)) c1 = Process(target=consume, args=(q,)) c2 = Process(target=consume, args=(q,)) p1.start() p2.start() p3.start() c1.start() c2.start() p1.join() p2.join() p3.join() q.put(None) q.put(None) print("zhu")from multiprocessing import Process, Queueimport timeimport randomdef producer(q): for i in range(3): res = "包子%s" % i time.sleep(0.5) print("生產了%s" % res) q.put(res) def consume(q): while True: res = q.get() if not res: break time.sleep(random.randint(1, 3)) print("吃了%s" % res) if __name__ == ‘__main__‘: q = Queue() p1 = Process(target=producer, args=(q,)) p2 = Process(target=producer, args=(q,)) p3 = Process(target=producer, args=(q,)) c1 = Process(target=consume, args=(q,)) c2 = Process(target=consume, args=(q,)) p1.start() p2.start() p3.start() c1.start() c2.start() p1.join() p2.join() p3.join() q.put(None) q.put(None) print("zhu")
JoinableQueue([maxsize])
from multiprocessing import Process, JoinableQueueimport timeimport randomdef producer(q): for i in range(3): res = "包子%s" % i time.sleep(0.5) print("生產了%s" % res) q.put(res) q.join() # 等消費者把所有資料取走之後,生產者才結束 def consume(q): while True: res = q.get() if not res: break time.sleep(random.randint(1, 3)) print("吃了%s" % res) q.task_done() # 發送訊號給q.join(),說明已經從隊列中取走一個資料並處理完畢if __name__ == ‘__main__‘: q = JoinableQueue() p1 = Process(target=producer, args=(q,)) p2 = Process(target=producer, args=(q,)) p3 = Process(target=producer, args=(q,)) c1 = Process(target=consume, args=(q,)) c2 = Process(target=consume, args=(q,)) c1.daemon = True c2.daemon = True p1.start() p2.start() p3.start() c1.start() c2.start() p1.join() p2.join() p3.join() print("zhu")
python之進程