2017-01-05 64 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

是的,你可以在任何结构中存储线程对象,这是没有问题的。 –