1

我試圖實現可以訪問共享數據資源的多處理應用程序。我正在使用鎖定機制來確保共享資源安全訪問。但是我打錯了。令人驚訝的是,如果進程1首先獲取鎖,它正在爲請求提供服務,並且它正在嘗試獲取鎖的下一個進程失敗。但是,如果除1以外的其他進程試圖首先獲取鎖,則它將在第一次運行時失敗。我是新來的Python和使用文檔,以實現這個所以我不知道如果我錯過任何基本的安全機制here.Any數據點作爲爲什麼我目睹這將是很大的幫助獲取鎖時Python多處理鎖機制失敗

方案:

#!/usr/bin/python 
from multiprocessing import Process, Manager, Lock 
import os 
import Queue 
import time 
lock = Lock() 
def launch_worker(d,l,index): 
    global lock 
    lock.acquire() 
    d[index] = "new" 
    print "in process"+str(index) 
    print d 
    lock.release() 
    return None 

def dispatcher(): 
    i=1 
    d={} 
    mp = Manager() 
    d = mp.dict() 
    d[1] = "a" 
    d[2] = "b" 
    d[3] = "c" 
    d[4] = "d" 
    d[5] = "e" 
    l = mp.list(range(10)) 
    for i in range(4): 
     p = Process(target=launch_worker, args=(d,l,i)) 
     i = i+1 
     p.start() 
    return None 

if __name__ == '__main__': 
    dispatcher() 

ERROR當處理1被服務第一

in process0 
{0: 'new', 1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'} 
Process Process-3: 
Traceback (most recent call last): 
    File "/usr/lib/python2.6/multiprocessing/process.py", line 232, in _bootstrap 
    self.run() 
    File "/usr/lib/python2.6/multiprocessing/process.py", line 88, in run 
    self._target(*self._args, **self._kwargs) 
    File "dispatcher.py", line 10, in launch_worker 
    d[index] = "new" 
    File "<string>", line 2, in __setitem__ 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 722, in _callmethod 
    self._connect() 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 709, in _connect 
    conn = self._Client(self._token.address, authkey=self._authkey) 
    File "/usr/lib/python2.6/multiprocessing/connection.py", line 143, in Client 
    c = SocketClient(address) 
    File "/usr/lib/python2.6/multiprocessing/connection.py", line 263, in SocketClient 
    s.connect(address) 
    File "<string>", line 1, in connect 
error: [Errno 2] No such file or directory 

ERROR當處理2首先服務

Process Process-2: 
Traceback (most recent call last): 
    File "/usr/lib/python2.6/multiprocessing/process.py", line 232, in _bootstrap 
    self.run() 
    File "/usr/lib/python2.6/multiprocessing/process.py", line 88, in run 
    self._target(*self._args, **self._kwargs) 
    File "dispatcher.py", line 10, in launch_worker 
    d[index] = "new" 
    File "<string>", line 2, in __setitem__ 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 722, in _callmethod 
    self._connect() 
    File "/usr/lib/python2.6/multiprocessing/managers.py", line 709, in _connect 
    conn = self._Client(self._token.address, authkey=self._authkey) 
    File "/usr/lib/python2.6/multiprocessing/connection.py", line 150, in Client 
    deliver_challenge(c, authkey) 
    File "/usr/lib/python2.6/multiprocessing/connection.py", line 373, in deliver_challenge 
    response = connection.recv_bytes(256)  # reject large message 
IOError: [Errno 104] Connection reset by peer 

回答

1

您的工作人員修改的字典是由調度過程管理的共享對象;工人對該對象的修改要求他們與調度過程進行通信。您看到的錯誤來自您的調度員在啓動它們之後並未等待工作進程的事實;它過早退出,所以它們可能不存在讓他們在需要時進行溝通。

嘗試更新共享字典的第一個或兩個工作人員可能會成功,因爲當他們修改共享字典時,包含Manager實例的進程可能仍然存在(例如,它可能仍在創建更多工作人員的過程中) 。因此在你的例子中你看到一些成功輸出。但管理過程很快就會退出,而下一個嘗試進行修改的員工將會失敗。 (您看到的錯誤消息通常是進程間通信失敗的嘗試;如果您再次運行程序,您可能會看到EOF錯誤。)

您需要做的是調用join方法在Process對象作爲一種等待他們每個人退出的方式。您的dispatcher的以下修改顯示了基本思路:

def dispatcher(): 
    mp = Manager() 
    d = mp.dict() 
    d[1] = "a" 
    d[2] = "b" 
    d[3] = "c" 
    d[4] = "d" 
    d[5] = "e" 
    procs = [] 
    for i in range(4): 
     p = Process(target=launch_worker, args=(d,i)) 
     procs.append(p) 
     p.start() 
    for p in procs: 
     p.join() 
+0

對我來說是非常有意義的。父進程正在退出。但我可能不想使用連接,因爲它可能會使我的程序序列化,因爲我希望獨立處理每個進程。我可能想睡在父功能中,除非有任何子進程通知。 – pavan