摘要:連接帶遠(yuǎn)程管理器對象,該對象的地址在構(gòu)造函數(shù)中支出。在當(dāng)前進(jìn)程中運(yùn)行管理器服務(wù)器。啟動一個(gè)單的子進(jìn)程,并在該子進(jìn)程中啟動管理器服務(wù)器。如果無法序列號對象將引發(fā)異常。
上一篇文章:Python進(jìn)程專題6:共享數(shù)據(jù)與同步
下一篇文章:Python進(jìn)程專題8:分布集群的消息傳遞
進(jìn)程不支持共享對象,上面描述的創(chuàng)建共享值和數(shù)組,但都是指定的特殊類型,對高級的Python對象(如:字典、列表、用戶自定義類的實(shí)例)不起作用。語法:還好multiprocessing模塊提供了一種使用共享對象的途徑:單前提是這些對象運(yùn)行在所謂的【管理器】的控制之下。
管理器是獨(dú)立的子進(jìn)程,其中存在真實(shí)的對象,并以服務(wù)器的形式運(yùn)行,其他進(jìn)程通過使用代理訪問共享對象,這些
代理作為管理器服務(wù)器的客戶端而運(yùn)行。
m=Manager():在一個(gè)獨(dú)立的進(jìn)程中創(chuàng)建運(yùn)行的管理器,返回值是SyncManager(定義在multiprocess.managersa模塊中)類的實(shí)例。 m可以創(chuàng)建共享對象常用方法
在服務(wù)器上創(chuàng)建共享的Array實(shí)例并返回可以訪問它的代理。
在服務(wù)器上創(chuàng)建共享的threading.BoundedSemphore實(shí)例,并返回可訪問它的代理。
在服務(wù)器上創(chuàng)建共享的threading.Condition實(shí)例,并返回可訪問它的代理。 lock是m.Lock()或m.Rlock()方法創(chuàng)建的代理實(shí)例
在服務(wù)器上創(chuàng)建共享的dict(字典)實(shí)例,并返回可以訪問它的代理。
在服務(wù)器上創(chuàng)建共享的thread.Event實(shí)例,并返回可以訪問它的代理。
在服務(wù)器上創(chuàng)建共享的list實(shí)例,并返回可以訪問它的代理。
子服務(wù)器上創(chuàng)建共享的threading.Lock實(shí)例,并返回可訪問它的代理。
在服務(wù)器創(chuàng)建共享的namespace對象,并返回可以訪問它的代理。 namespace就是一個(gè)類似于Python模塊的對象。例如:如果n是一個(gè)命名空間代理,那么可以使用(.)賦值和讀取屬性, 例如:n.name=value 或value=n.name。但name的名稱十分重要,如果name以字母開頭,那么這個(gè)值就是管理器所擁有的共享對象的一部分, 所有其它進(jìn)程均可訪問它,如果name以下劃線開頭,那么它只是代理對象的一部分,并不是共享。
在服務(wù)器上創(chuàng)建共享的Queue.Queue對象,并返回可訪問它的代理。
在服務(wù)器上創(chuàng)建共享的threading.Rlick對象,并返回可訪問它的代理。
在服務(wù)器上創(chuàng)建共享的threading.Semaphore對象,并返回可訪問它的代理。
在服務(wù)器上創(chuàng)建一個(gè)共享的Value對象,并返回可訪問它的代理。
#使用管理器創(chuàng)建一個(gè)在進(jìn)程間共享的字典 import multiprocessing import time def watch(dict,event): while True: event.wait() print(dict) event.clear() if __name__=="__main__": #實(shí)例化一個(gè)管理器 m=multiprocessing.Manager() #在服務(wù)器上創(chuàng)建一個(gè)共享的字典,并返回可以調(diào)用它的代理 dict=m.dict() #在服務(wù)器上創(chuàng)建一個(gè)共享的Event event=m.Event() #啟動監(jiān)視字典的進(jìn)程 p=multiprocessing.Process(target=watch,args=(dict,event,)) #設(shè)置為后臺進(jìn)程,隨主進(jìn)程的銷毀而銷毀,該后臺進(jìn)程無法創(chuàng)建新的線程 p.daemon=True p.start() #更新字典并通知監(jiān)聽者 dict["name"]="mark" event.set() time.sleep(3) # 更新字典并通知監(jiān)聽者 dict["age"] = 18 event.set() time.sleep(3) #終止進(jìn)程和管理器 p.terminate() m.shutdown()
運(yùn)行結(jié)果:
繼承BaseManager類,實(shí)現(xiàn)自定義對象的共享如果想要共享用戶自定義類的實(shí)例,則必須創(chuàng)建自定義管理器對象,為此,需要創(chuàng)建一個(gè)繼承自BaseManager類的類,其中BaseManager類定義在multiprocessing.managers子模塊中。
managers.BaseManager(address,authkey):用戶自定對象創(chuàng)建管理器服務(wù)器的基類。 address是一個(gè)可選的元組(hostname,port),用于指定服務(wù)器的網(wǎng)絡(luò)地址。如果忽略此參數(shù),操作系統(tǒng)將簡單 的分配一個(gè)對應(yīng)于某些空閑端口號的地址。 authkey是一個(gè)字符串,用于對連接到服務(wù)器的客戶端身份進(jìn)行驗(yàn)證。如果忽略此參數(shù),將是喲個(gè)current_process().authkey的值。
假設(shè)myclass是一個(gè)繼承自BaseManager的類,可以使用以下類方法來創(chuàng)建用于返回代理給共享對象的方法。
myclass.register(typeid,callable,proxytype,exposed,method_to_typeid,create_method):使用管理器類注冊一種新的數(shù)據(jù)類型。 typeid:一個(gè)字符串,用于命名特殊類型的共享對象。這個(gè)字符串應(yīng)該是有效的Python標(biāo)識符。 callable:創(chuàng)建或返回要共享的實(shí)例的可調(diào)用對象。 proxytype:一個(gè)類,負(fù)責(zé)提供客戶端中藥使用的代理對象的實(shí)現(xiàn),通常這些類是默認(rèn)生成的,因此一般設(shè)置為None。 exposed:共享對象上方法名的序列,它將會公開給代理對象,如果省略此參數(shù),將使用proxytype_exposed的值, 如果proxytype_expose未定義,序列將包含所有的公共方法(所有不以下劃線_開頭的可調(diào)用方法)。 method_to_typeid:從方法名稱到類型IDS的映射,這里的IDS用于指定哪些方法應(yīng)該使用代理對象返回他們的結(jié)果, 如果某個(gè)方法在這個(gè)映射中找不到,將復(fù)制和返回它的返回值,如果method_to_typeid為None,將使用proxytype_method_to_typeid_的值。 create_method:一個(gè)布爾標(biāo)志,用于指定是否在mgclass中創(chuàng)建名為typeid的方法,默認(rèn)值為True。
從BaseManager類派生的管理器的實(shí)例m必須手動啟動才能運(yùn)行。
屬性或者方法 | 解釋說明 |
---|---|
m.address | 元組(hostname,port),代表管理器服務(wù)器正在使用的地址。 |
m.connect() | 連接帶遠(yuǎn)程管理器對象,該對象的地址在BaseManager構(gòu)造函數(shù)中支出。 |
m.serve_forever() | 在當(dāng)前進(jìn)程中運(yùn)行管理器服務(wù)器。 |
m.shutdown() | 關(guān)閉由start()啟動的管理器服務(wù)器。 |
m.start() | 啟動一個(gè)單的子進(jìn)程,并在該子進(jìn)程中啟動管理器服務(wù)器。 |
繼承自BaseProxy的類的實(shí)例具有以下方法:
proxy._callmethod(name,args,kwargs):調(diào)用代理引用對象上的方法name。 proxy._getvalue():返回調(diào)用者中引用對象的副本,如果這次調(diào)用是在另一個(gè)進(jìn)程中, 那么引用對象將被序列化,發(fā)送給調(diào)用者,然后再進(jìn)行反序列化。如果無法序列號對象將引發(fā)異常。
代碼:
#繼承BaseManager類,實(shí)現(xiàn)自定義對象的共享,利用代理公開屬性與方法 import multiprocessing from multiprocessing.managers import BaseManager from multiprocessing.managers import BaseProxy #普通需要共享的類,代理無法通過(.)這種形式直接訪問屬性 class MyClass(): def __init__(self,value): self.name=value def __repr__(self): return "MyClass(%s)"%self.name def getName(self): return self.name def setName(self,value): self.name=value def __add__(self,valuye): self.name+=valuye return self #通過自定義繼承BaseProxy來實(shí)現(xiàn)代理,從而正確的公開__add__方法,并使用特性(property)公開name屬性。 #BaseProxy來來自multiprocessing.managers模塊 class MyClassProxy(BaseProxy): #referent上公開的所有方法列表 _exxposed_=["__add__","getName","setName"] #實(shí)現(xiàn)代理的公共結(jié)接口 def __add__(self, value): self._callmethod("__add__",(value,)) return self @property def name(self): return self._callmethod("getName",()) @name.setter def name(self,value): self._callmethod("setName",(value,)) def __repr__(self): return "MyClass(%s)"%self.name def getName(self): return self.name def setName(self,value): self.name=value def __add__(self,valuye): self.name+=valuye return self class MyManager(BaseManager): pass #不使用代理 #MyManager.register("MyClass",MyClass) #使用代理 MyManager.register("MyClass",MyClass,proxytype=MyClassProxy) if __name__=="__main__": m=MyManager() m.start() #創(chuàng)建托管對象,此時(shí)知識創(chuàng)建了一個(gè)實(shí)例代理,無法直接訪問屬性,必須使用函數(shù)來訪問 #代理無法訪問特殊方法和下劃線(_)開頭的所有方法。 a=m.MyClass("mark") print(a) print(a.getName()) #不使用代理,下面兩條語句會異常 a.__add__("帥哥") print(a.name) #print(a.name) #a.__add__("帥哥")
結(jié)果:
MyClass(mark) mark mark帥哥
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/42354.html
摘要:可以使用標(biāo)準(zhǔn)的索引切片迭代操作訪問它,其中每項(xiàng)操作均鎖進(jìn)程同步,對于字節(jié)字符串,還具有屬性,可以把整個(gè)數(shù)組當(dāng)做一個(gè)字符串進(jìn)行訪問。當(dāng)所編寫的程序必須一次性操作大量的數(shù)組項(xiàng)時(shí),如果同時(shí)使用這種數(shù)據(jù)類型和用于同步的單獨(dú)大的鎖,性能將極大提升。 上一篇文章:Python進(jìn)程專題5:進(jìn)程間通信下一篇文章:Python進(jìn)程專題7:托管對象 我們現(xiàn)在知道,進(jìn)程之間彼此是孤立的,唯一通信的方式是隊(duì)...
摘要:代表網(wǎng)絡(luò)地址的元組或者代表域套接字的文件名,或者代表形式的字符串,代表遠(yuǎn)程系統(tǒng)本地計(jì)算機(jī)的為上的一條命名管道。是一個(gè)整數(shù),當(dāng)參數(shù)指定了一個(gè)網(wǎng)絡(luò)連接時(shí),對應(yīng)于傳遞給套接字的方法的值,默認(rèn)為。 上一篇文章:Python進(jìn)程專題7:托管對象下一篇文章:Python進(jìn)程專題9:關(guān)于進(jìn)程的實(shí)用工具函數(shù) 使用multiprocessing模塊的程序不僅可以于運(yùn)行在同一計(jì)算機(jī)的其它程序進(jìn)行消息傳遞...
摘要:上一篇文章進(jìn)程專題完結(jié)篇多進(jìn)程處理的一般建議下一篇文章線程專題多線程使用的必要性進(jìn)程線程進(jìn)程能夠完成多任務(wù),比如在一個(gè)電腦上可以運(yùn)行多個(gè)軟件。由于占用資源少,也使得多線程程序并發(fā)比較高。 上一篇文章:Python進(jìn)程專題完結(jié)篇:多進(jìn)程處理的一般建議下一篇文章:Python線程專題1:多線程使用的必要性 進(jìn)程VS線程 進(jìn)程:能夠完成多任務(wù),比如在一個(gè)電腦上可以運(yùn)行多個(gè)軟件。線程:也能夠...
摘要:上一篇文章進(jìn)程專題繼承來創(chuàng)建進(jìn)程下一篇文章進(jìn)程專題進(jìn)程間通信當(dāng)我們需要創(chuàng)建大量的進(jìn)程時(shí),利用模塊提供的來創(chuàng)建進(jìn)程。關(guān)閉進(jìn)程池,不再接受進(jìn)的進(jìn)程請求,但已經(jīng)接受的進(jìn)程還是會繼續(xù)執(zhí)行。 上一篇文章:Python進(jìn)程專題3:繼承Process來創(chuàng)建進(jìn)程下一篇文章:Python進(jìn)程專題5:進(jìn)程間通信 當(dāng)我們需要創(chuàng)建大量的進(jìn)程時(shí),利用multiprocessing模塊提供的Pool來創(chuàng)建進(jìn)程。 ...
摘要:類常用屬性布爾值,指示進(jìn)程是否是后臺進(jìn)程。當(dāng)創(chuàng)建它的進(jìn)程終止時(shí),后臺進(jìn)程會自動終止。進(jìn)程的整數(shù)退出指令。如果進(jìn)程仍然在運(yùn)行,它的值為,如果值為負(fù)數(shù),就表示進(jìn)程由信號所終止。 上一篇文章:Python進(jìn)程專題1:fork():創(chuàng)建子進(jìn)程、getpid()、getppid()下一篇文章:Python進(jìn)程專題3:繼承Process來創(chuàng)建進(jìn)程 由于fork()無法對Windows使用,而py...
閱讀 4025·2023-04-25 21:09
閱讀 3223·2021-10-20 13:48
閱讀 3221·2021-09-24 10:25
閱讀 3025·2021-08-21 14:08
閱讀 1896·2019-08-30 15:56
閱讀 1072·2019-08-30 15:52
閱讀 1976·2019-08-29 14:11
閱讀 3669·2019-08-29 11:01