multiprocessing global variable updates not returned to parent

后端 未结 5 506
天命终不由人
天命终不由人 2020-11-22 10:44

I am trying to return values from subprocesses but these values are unfortunately unpicklable. So I used global variables in threads module with success but have not been ab

5条回答
  •  野趣味
    野趣味 (楼主)
    2020-11-22 11:06

    @DBlas gives you a quick url and reference to the Manager class in an answer, but I think its still a bit vague so I thought it might be helpful for you to just see it applied...

    import multiprocessing
    from multiprocessing import Manager
    
    ants = ['DV03', 'DV04']
    
    def getDV03CclDrivers(lib, data_dict):  
        data_dict[1] = 1
        data_dict[0] = 0
    
    def getDV04CclDrivers(lib, data_list):   
        data_list['driver'] = 0  
    
    
    if __name__ == "__main__":
    
        manager = Manager()
        dataDV03 = manager.list(['', ''])
        dataDV04 = manager.dict({'driver': '', 'status': ''})
    
        jobs = []
        if 'DV03' in ants:
            j = multiprocessing.Process(
                    target=getDV03CclDrivers, 
                    args=('LORR', dataDV03))
            jobs.append(j)
    
        if 'DV04' in ants:
            j = multiprocessing.Process(
                    target=getDV04CclDrivers, 
                    args=('LORR', dataDV04))
            jobs.append(j)
    
        for j in jobs:
            j.start()
    
        for j in jobs:
            j.join()
    
        print 'Results:\n'
        print 'DV03', dataDV03
        print 'DV04', dataDV04
    

    Because multiprocessing actually uses separate processes, you cannot simply share global variables because they will be in completely different "spaces" in memory. What you do to a global under one process will not reflect in another. Though I admit that it seems confusing since the way you see it, its all living right there in the same piece of code, so "why shouldn't those methods have access to the global"? Its harder to wrap your head around the idea that they will be running in different processes.

    The Manager class is given to act as a proxy for data structures that can shuttle info back and forth for you between processes. What you will do is create a special dict and list from a manager, pass them into your methods, and operate on them locally.

    Un-pickle-able data

    For your specialize LORR object, you might need to create something like a proxy that can represent the pickable state of the instance.

    Not super robust or tested much, but gives you the idea.

    class LORRProxy(object):
    
        def __init__(self, lorrObject=None):
            self.instance = lorrObject
    
        def __getstate__(self):
            # how to get the state data out of a lorr instance
            inst = self.instance
            state = dict(
                foo = inst.a,
                bar = inst.b,
            )
            return state
    
        def __setstate__(self, state):
            # rebuilt a lorr instance from state
            lorr = LORR.LORR()
            lorr.a = state['foo']
            lorr.b = state['bar']
            self.instance = lorr
    

提交回复
热议问题