2017-01-05 65 views
0

我想在兩個進程之間共享一個線程對象的字典。我還有另一個目前似乎有效的對象字典。python在兩個進程之間的manager.dict()中共享線程對象

的問題是,它會引發一個例外,當我嘗試鍵/值對添加到字典(key是整數,value在線程對象):

Exception with manager.dict() 
    TypeError: can't pickle _thread.lock objects 

我嘗試從切換manager.dict()manager.list(),它不工作之一:

Exception with manager.list() 
    TypeError: can't pickle _thread.lock objects 

readFiles()功能是否正常工作。

我使用Python 3.5.1(Anaconda)的

def startAlgorithm(fNameGraph, fNameEnergyDistribution, fNameRouteTables): 
    global _manager, _allTiesets, _allNodes, _stopDistribution 

    _manager = Manager() 
    _allTiesets = _manager.dict() 
    _allNodes = _manager.dict() 

    _stopDistribution = Value(c_bool, False) 

    readFiles(fNameGraph, fNameEnergyDistribution, fNameRouteTables) 
    initializeAlgorithm() 

    procTADiC = Process(target=TADiC, args=(_stopDistribution, _allNodes)) 
    procTA = Process(target=TIESET_AGENT, args=(_stopDistribution, _allNodes, _allTiesets)) 
    procTADiC.start() 
    procTA.start() 

    procTADiC.join() 
    procTA.join() 


def initializeAlgorithm(): 
    global _graphNX, _routingTable, _energyDistribution, _energyMeanValue 

    #Init all Nodes 
    allNodeIDs = _graphNX.nodes() 
    energySum = 0 
    for node in allNodeIDs: 
     nodeEnergyLoad = float(_energyDistribution.get(str(node))) 
     nodeObj = Node(node, nodeEnergyLoad) 
     _allNodes[node] = nodeObj 
     energySum = energySum + nodeEnergyLoad 

    #Calculate the mean value from the whole energy in the graph 
    _energyMeanValue = energySum/len(allNodeIDs) 

    #Init all Tieset-Threads 
    for tieset in _routingTable: 
     tiesetID = int(tieset['TiesetID']) 
     connNodes = list(tieset['Nodes']) 
     connEdges = list(tieset['Edges']) 
     adjTiesets = list(tieset['AdjTiesets']) 
     tiesetThread = Tieset(tiesetID, connNodes, connEdges, adjTiesets) 
     _allTiesets[tiesetID] = tiesetThread  # Raise Exception!!!!!!!!!! 


class Node: 
    'Node-Class that hold information about a node in a tieset' 

    def __init__(self, nodeID, energyLoad): 
     self.nodeID = nodeID 
     self.energyLoad = energyLoad 
     self.tiesetFlag = False 


class Tieset(threading.Thread): 
    'Tieset-Class as Thread to distribute the load within the tieset' 

    def __init__(self, tiesetID, connectedNodes, connectedEdges, adjTiesets): 
     threading.Thread.__init__(self) 
     self.tiesetID = tiesetID 
     self.connectedNodes = connectedNodes 
     self.connectedEdges = connectedEdges 
     self.adjTiesets = adjTiesets 
     self.leaderNodeID = min(int(n) for n in connectedNodes) 
     self.measureCnt = 0 


    def run(self): 
     print('start Thread') 
+0

你有什麼異常?將異常追蹤添加到問題中。 – asherbar

+0

當我使用dict()它引發異常... TypeError:無法序列化'_io.TextIOWrapper'對象 –

+0

當我使用列表它引發異常... TypeError:不能pickle _thread.lock對象 –

回答

0

我可以說,你不能在進程間共享線程,可以爲那些線程共享的參數,如果你想開始他們在不同的過程,或者你可以分享一些結果。你看到的問題是該進程創建的本質引起的,在python中,所有參數將在當前進程中被序列化,然後傳遞給一個新進程,然後python將反序列化它們以運行「目標」。顯然,線程對象是不可序列化的(你可以檢查這個有趣的線程來理解序列化問題debugging pickle)。

+0

謝謝,for這個答案,我嘗試去思考如何以不同的方式處理這個問題......當我想要將它們存儲在列表中(而不是在manager.list()中)時,是否需要醃製線程對象? –

+0

問題是線程對象不可序列化,您可以實現自己的序列化程序/反序列化程序,但不能在另一個進程中使用相同的線程。 –

+0

是的,你可以在任何結構中存儲線程對象,這是沒有問題的。 –