为了账号安全,请及时绑定邮箱和手机立即绑定

未返回给父级的多处理全局变量更新

未返回给父级的多处理全局变量更新

弑天下 2019-08-03 12:03:48
未返回给父级的多处理全局变量更新我试图从子进程返回值,但不幸的是,这些值是不可选择的。因此,我成功地在线程模块中使用了全局变量,但在使用多处理模块时无法检索子进程中完成的更新。我希望我错过了什么。在结尾处打印的结果总是与给定vars的初始值相同。dataDV03和dataDV04..子进程正在更新这些全局变量,但是这些全局变量在父进程中保持不变。import multiprocessing# NOT ABLE to get python to return values in passed variables.ants = ['DV03', 'DV04']dataDV03 = ['', '']dataDV04 = {'driver': '', 'status': ''}def getDV03CclDrivers(lib):  # call global variable     global dataDV03     dataDV03[1] = 1     dataDV03[0] = 0# eval( 'CCL.' + lib + '.' +  lib + '( "DV03" )' ) these are unpicklable instantiationsdef getDV04CclDrivers(lib, dataDV04):   # pass global variable     dataDV04['driver'] = 0  # eval( 'CCL.' + lib + '.' +  lib + '( "DV04" )' )if __name__ == "__main__":     jobs = []     if 'DV03' in ants:         j = multiprocessing.Process(target=getDV03CclDrivers, args=('LORR',))         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我不能张贴到我的问题,所以将尝试编辑原件。以下是不可选择的对象:In [1]: from CCL import LORR In [2]: lorr=LORR.LORR('DV20', None) In [3]: lorr Out[3]: <CCL.LORR.LORR instance at 0x94b188c>这是在使用多进程时返回的错误。池将实例返回给父进程:Thread getCcl (('DV20', 'LORR'),) Process PoolWorker-1: Traceback (most recent call last): File "/alma/ACS-10.1/casa/lib/python2.6/multiprocessing/process.py", line 232, in _bootstrap self.run() File "/alma/ACS-10.1/casa/lib/python2.6/multiprocessing/process.py", line 88, in run self._target(*self._args, **self._kwargs) File "/alma/ACS-10.1/casa/lib/python2.6/multiprocessing/pool.py", line 71, in worker put((job, i, result)) File "/alma/ACS-10.1/casa/lib/python2.6/multiprocessing/queues.py", line 366, in put return send(obj) UnpickleableError: Cannot pickle <type 'thread.lock'> objects
查看完整描述

3 回答

?
开心每一天1111

TA贡献1836条经验 获得超13个赞

在回答中给出了一个快速的url和对Manager类的引用,但是我认为它仍然有点模糊,所以我认为可能会帮助您看到它的应用.

import multiprocessingfrom multiprocessing import Managerants = ['DV03', 'DV04']def getDV03CclDrivers(lib, data_dict):  
    data_dict[1] = 1
    data_dict[0] = 0def 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

因为多处理实际上使用单独的进程,所以不能简单地共享全局变量,因为它们将位于内存中完全不同的“空间”中。你在一个过程中对全局所做的事情不会在另一个过程中反映出来。尽管我承认,从你的角度来看,这似乎让人困惑,但所有这些方法都存在于同一段代码中,所以“为什么这些方法不应该访问全局的呢?”很难让你的头脑明白,它们将在不同的过程中运行。

这个经理班作为数据结构的代理,可以在进程之间来回传送信息。您要做的是从管理人员创建一个特殊的DECT和列表,将它们传递到您的方法中,并在本地对它们进行操作。

不可分离的数据

对于您的专用Lorr对象,您可能需要创建类似于代理的东西,该代理可以表示实例的可选择状态。

不是超级健壮或测试很多,但给你的想法。

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



查看完整回答
反对 回复 2019-08-04
?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

您也可以使用多处理阵列..这允许您在进程之间拥有共享状态,并且可能是最接近全局变量的状态。

在main的顶部,声明Array。第一个参数‘i’表示它将是整数。第二个参数给出了初始值:

shared_dataDV03 = multiprocessing.Array ('i', (0, 0)) #a shared array

然后将这个数组作为参数传递给进程:

j = multiprocessing.Process(target=getDV03CclDrivers, args=('LORR',shared_dataDV03))

您必须在被调用的函数中接收数组参数,然后可以在函数中修改它:

def getDV03CclDrivers(lib,arr):  # call global variable
    arr[1]=1
    arr[0]=0

该数组与父数组共享,因此您可以在父文件的末尾打印出值:

print 'DV03', shared_dataDV03[:]

它将显示这些变化:

DV03 [0, 1]




查看完整回答
反对 回复 2019-08-04
  • 3 回答
  • 0 关注
  • 396 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信