2 并发编程--开启进程的两种方式
multiprocessing??英?/m?lt?'pr??ses??/?n. [計(jì)][通信] 多重處理
1、multiprocessing 模塊介紹
python中的多線程無(wú)法利用多核優(yōu)勢(shì),如果想要充分地使用多核CPU的資源(os.cpu\_count\(\)查看),在python中大部分情況需要使用多進(jìn)程。
Python提供了multiprocessing。 multiprocessing模塊用來(lái)開(kāi)啟子進(jìn)程,并在子進(jìn)程中執(zhí)行我們定制的任務(wù)(比如函數(shù)),該模塊與多線程模塊threading的編程接口類似。multiprocessing模塊的功能眾多:支持子進(jìn)程、通信和共享數(shù)據(jù)、執(zhí)行不同形式的同步,>提供了Process、Queue、Pipe、Lock等組件。
需要再次強(qiáng)調(diào)的一點(diǎn)是:與線程不同,進(jìn)程沒(méi)有任何共享狀態(tài),進(jìn)程修改的數(shù)據(jù),改動(dòng)僅限于該進(jìn)程內(nèi)。
2、Process類的介紹
創(chuàng)建進(jìn)程的類:
Process([group [, target [, name [, args [, kwargs]]]]]),由該類實(shí)例化得到的對(duì)象,可用來(lái)開(kāi)啟一個(gè)子進(jìn)程強(qiáng)調(diào): 1. 需要使用關(guān)鍵字的方式來(lái)指定參數(shù)
2. args指定的為傳給target函數(shù)的位置參數(shù),是一個(gè)元組形式,必須有逗號(hào)
參數(shù)介紹:
group參數(shù)未使用,值始終為Nonetarget表示調(diào)用對(duì)象,即子進(jìn)程要執(zhí)行的任務(wù)args表示調(diào)用對(duì)象的位置參數(shù)元組,args=(1,2,'egon',)kwargs表示調(diào)用對(duì)象的字典,kwargs={'name':'egon','age':18}name為子進(jìn)程的名稱
方法介紹:
p.start():啟動(dòng)進(jìn)程,并調(diào)用該子進(jìn)程中的p.run()
p.run():進(jìn)程啟動(dòng)時(shí)運(yùn)行的方法,正是它去調(diào)用target指定的函數(shù),我們自定義類的類中一定要實(shí)現(xiàn)該方法 p.terminate():強(qiáng)制終止進(jìn)程p,不會(huì)進(jìn)行任何清理操作,如果p創(chuàng)建了子進(jìn)程,該子進(jìn)程就成了僵尸進(jìn)程,使用該方法需要特別小心這種情況。如果p還保存了一個(gè)鎖那么也將不會(huì)被釋放,進(jìn)而導(dǎo)致死鎖
p.is_alive():如果p仍然運(yùn)行,返回Truep.join([timeout]):主線程等待p終止(強(qiáng)調(diào):是主線程處于等的狀態(tài),而p是處于運(yùn)行的狀態(tài))。timeout是可選的超時(shí)時(shí)間。 屬性介紹:
p.daemon:默認(rèn)值為False,如果設(shè)為True,代表p為后臺(tái)運(yùn)行的守護(hù)進(jìn)程,當(dāng)p的父進(jìn)程終止時(shí),p也隨之終止,并且設(shè)定為True后,p不能創(chuàng)建自己的新進(jìn)程,必須在p.start()之前設(shè)置p.name:進(jìn)程的名稱p.pid:進(jìn)程的pid 3、Process類的使用
注意:在windows中Process()必須放到# if __name__=='__main__':下:
創(chuàng)建并開(kāi)啟子進(jìn)程的方式一:
方式一 from multiprocessing import Process import time,random def task(name):print(f"{name} is running")time.sleep(3)print(f"{name} is done") if __name__ == '__main__':# target表示調(diào)用對(duì)象,即子進(jìn)程要執(zhí)行的任務(wù)# args 表示調(diào)用對(duì)象的位置參數(shù)元組,args = (1,2,)# name 位子進(jìn)程的名稱 實(shí)例化對(duì)象p = Process(target=task,args=('子進(jìn)程1',)) # 初始化對(duì)象p.start() # 僅僅只是給操作系統(tǒng)發(fā)送一個(gè)信號(hào)print('主進(jìn)程') #----------------------------------------------------------- 主 子進(jìn)程1 is running 子進(jìn)程1 is done
創(chuàng)建并開(kāi)啟子進(jìn)程的方式二:
import time import random from multiprocessing import Process class MyProcess(Process):def __init__(self,name):self.name = namesuper().__init__()self.name = namedef run(self):print(f"{self.name} is running")time.sleep(random.randrange(1,3))print(f"{self.name} id done") if __name__ == '__main__':p = MyProcess('子進(jìn)程1')p.start()print('主')
?4、練習(xí)題
4.1、思考開(kāi)啟進(jìn)程的方式一和方式二各開(kāi)啟了幾個(gè)進(jìn)程?
?一個(gè)主進(jìn)程,一個(gè)子進(jìn)程
4.2、進(jìn)程之間的內(nèi)存空間是共享的還是隔離的?下述代碼的執(zhí)行結(jié)果是什么?
from multiprocessing import Processn=100 #在windows系統(tǒng)中應(yīng)該把全局變量定義在if __name__ == '__main__'之上就可以了def work():global nn=0print('子進(jìn)程內(nèi): ',n)if __name__ == '__main__':p=Process(target=work)p.start()print('主進(jìn)程內(nèi): ',n)
輸出:
主進(jìn)程內(nèi): 100
子進(jìn)程內(nèi): 0
4.3、基于多進(jìn)程實(shí)現(xiàn)并發(fā)的套接字通信?
客戶端:
import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.connect(('127.0.0.1',8080)) while True:msg = input('>>>').strip()if not msg:continuephone.send(msg.encode('utf-8')) # send 發(fā)給操作系統(tǒng)了 data = phone.recv(1024)print(data.decode('utf-8')) phone.close()View Code
服務(wù)端:
import socket from multiprocessing import Process #由該類實(shí)例化得到的對(duì)象,可用來(lái)開(kāi)啟一個(gè)子進(jìn)程 def talk(conn):while True:try:data = conn.recv(10240).decode('utf-8')print(data)conn.send(data.upper().encode('utf-8'))except Exception as e:print(e)break def server(ip_port):Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)Server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 解決端口占用情況,操作系統(tǒng)回收端口慢Server.bind(('127.0.0.1', 8080))Server.listen(5)while True:conn,addr = Server.accept()p = Process(target=talk, args=(conn,))p.start()Server.close() if __name__ == '__main__':ip_port = ('127.0.0.1',8080)server(ip_port)View Code
?
4.4、思考每來(lái)一個(gè)客戶端,服務(wù)器就開(kāi)啟一個(gè)新的進(jìn)程來(lái)服務(wù)它,這種實(shí)現(xiàn)方式有無(wú)問(wèn)題?
?這種實(shí)現(xiàn)方式會(huì)造成占用過(guò)多的系統(tǒng)資源。
轉(zhuǎn)載于:https://www.cnblogs.com/foremostxl/p/9719284.html
總結(jié)
以上是生活随笔為你收集整理的2 并发编程--开启进程的两种方式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 上亏下亏?必采纳
- 下一篇: mysql 电商项目(一)