摘要:前面的文章介紹了如何進行進程間的通信方式。結下來我們來講一講如何管理多個進程對資源的訪問。正確的情況是,在一個進程寫完的時候,再讓另一個進程進行寫入。那么后的代碼塊都是被所保護。懷疑會在下出錯以上代碼可以正確執行。
前面的文章介紹了如何進行進程間的通信方式。結下來我們來講一講如何管理多個進程對資源的訪問。
例如有時候我們多個進程對某一個文件進行寫入的時候,如果我們一個進程還沒有寫完,就被CPU切換到另一個進程,勢必會造成文件寫入的順序亂七八糟的。正確的情況是,在一個進程寫完的時候,再讓另一個進程進行寫入。這時候,我們需要一個鎖。
Lock有一點像我們日常生活中上廁所。廁所就是我們的資源,可以解決我們的需求。但是廁所是有限的,而且一次只能進去一個人。同時想上廁所的人很多,還沒輪到的人全部在外邊等待,輪到的人可以進去使用廁所,同時會鎖上門,禁止其他人進入。上完廁所的人出來,打開廁所門,讓后面的人進來。
翻譯成計算機語言就是:
這個資源只允許一個Process訪問,因此只有一個門,上一把鎖。
from multiprocessing import Lock, Pool import random def write_file(lock): with lock: with open("write_demo.txt", "a") as wf: wf.write(str(random.random())+" ") if __name__ == "__main__": lock = Lock() pool = Pool() for i in range(0, 10): pool.apply_async(write_file(lock)) pool.close()
注意: lock其實跟文件的打開關閉一樣,可以使用with語句。
Lock supports the context manager protocol and thus may be used in with statements.
解釋一下這里為什么是with lock:因為在if __name__ == "__main__":中我們已經創建了Lock對象。而with后是需要跟一個對象,因此直接將lock寫在后面即可。那么with后的代碼塊都是被with所保護。
如果不用with語句的話,則需要手動寫:
lock.acquire() lock.release()
兩者之間的代碼才是被鎖保護的。
RLockRLock是Lock的遞歸版。啥意思呢?
我們知道lock.aquire()是請求鎖,當當前的鎖事鎖定狀態的時候,則lock.aquire()則會阻塞等待鎖釋放。
因此如果我們寫了兩個lock.aquire()則會產生死鎖。第二個lock.aquire()會永遠等待在那里。
使用RLock則不會有這種情況。RLock一個門支持多個鎖,上多少把鎖,就得釋放多少次。
Semaphore有信號燈的意思。
Semaphore跟Lock類似,但是Semaphore可以允許指定最多多少個進程訪問資源。
就像該資源有多個門,每個門一把鎖。一個進程訪問了資源,鎖了門,還有其他門可以使用。但是如果所有門都被使用了,那么就得等待有進程出來釋放鎖才可以。
在編寫Sempaphore示例代碼的時候,遇到了一個比較奇怪的問題。
from multiprocessing import Semaphore, Pool import os import time def worker_process(s): print id(s) with s: print "Process (%s) run" % os.getpid() time.sleep(1) print "Process (%s) ended" % os.getpid() if __name__ == "__main__": semaphore = Semaphore(1) print id(semaphore) pool = Pool(4) for i in range(0, 1000): pool.apply_async(worker_process, args=(semaphore,)) pool.close() pool.join() print "Main Process ended"
如上所示的代碼,傳遞semaphore時候,worker_process并不會執行。
但是如果將semaphore定義成一個全局變量,那么則可以在Linux或者unix下執行。(懷疑會在windows下出錯)
from multiprocessing import Semaphore, Pool import os import time semaphore = Semaphore(1) def worker_process(): print id(semaphore) with semaphore: print "Process (%s) run" % os.getpid() time.sleep(1) print "Process (%s) ended" % os.getpid() if __name__ == "__main__": print id(semaphore) pool = Pool(4) for i in range(0, 1000): pool.apply_async(worker_process) pool.close() pool.join() print "Main Process ended"
以上代碼可以正確執行。
暫時不知道問題出在哪里?有會的網友還請指點。
還有Event。Event也是用于進程間的通信,那么它跟Queue、Pipe有什么區別呢?
其實Python多進程還有許多的內容。在后續的文章中介紹。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/38356.html
摘要:連接帶遠程管理器對象,該對象的地址在構造函數中支出。在當前進程中運行管理器服務器。啟動一個單的子進程,并在該子進程中啟動管理器服務器。如果無法序列號對象將引發異常。 上一篇文章:Python進程專題6:共享數據與同步下一篇文章:Python進程專題8:分布集群的消息傳遞 進程不支持共享對象,上面描述的創建共享值和數組,但都是指定的特殊類型,對高級的Python對象(如:字典、列表、用...
摘要:很簡單,這個模塊實現了開辟一塊共享內存空間,就好比中的方法一樣,有興趣的同學可以去查閱。查了下資料,返回的對象控制了一個進程,可用于多進程之間的安全通信,其支持的類型有和等。 有關于 multiprocessing 中共享變量的問題 現在的cpu都很強大,比方我用的至強2620有24核可以同時工作,并行執行進程程序。這在計算密集型的程序是很需要的,如沙漠中的綠洲,令人重獲新生。那么,問...
摘要:可以使用標準的索引切片迭代操作訪問它,其中每項操作均鎖進程同步,對于字節字符串,還具有屬性,可以把整個數組當做一個字符串進行訪問。當所編寫的程序必須一次性操作大量的數組項時,如果同時使用這種數據類型和用于同步的單獨大的鎖,性能將極大提升。 上一篇文章:Python進程專題5:進程間通信下一篇文章:Python進程專題7:托管對象 我們現在知道,進程之間彼此是孤立的,唯一通信的方式是隊...
摘要:某進程內的線程在其它進程不可見。線程的實體包括程序數據和。包括以下信息線程狀態。當線程不運行時,被保存的現場資源。用戶級線程執行系統調用指令時將導致其所屬進程被中斷,而內核支持線程執行系統調用指令時,只導致該線程被中斷。線程能夠利用的表空 操作系統線程理論 線程概念的引入背景 進程之前我們已經了解了操作系統中進程的概念,程序并不能單獨運行,只有將程序裝載到內存中,系統為它分配資源才能運...
摘要:第四章分布式和并行計算來源譯者飛龍協議引言目前為止,我們專注于如何創建解釋和執行程序。一個交互的例子就是在線閱讀紐約時報。當上的服務器與瀏覽器客戶端比如通信時,它的任務就是發送回來紐約時報主頁的。消息有三個必要部分發送者接收者和內容。 第四章 分布式和并行計算 來源:Chapter 4: Distributed and Parallel Computing 譯者:飛龍 協議:CC B...
閱讀 904·2021-09-29 09:35
閱讀 1253·2021-09-28 09:36
閱讀 1522·2021-09-24 10:38
閱讀 1066·2021-09-10 11:18
閱讀 631·2019-08-30 15:54
閱讀 2496·2019-08-30 13:22
閱讀 1964·2019-08-30 11:14
閱讀 697·2019-08-29 12:35