Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 实例属性不会使用多处理持久化_Python_Python 3.x_Multithreading_Multiprocessing_Pathos - Fatal编程技术网

Python 实例属性不会使用多处理持久化

Python 实例属性不会使用多处理持久化,python,python-3.x,multithreading,multiprocessing,pathos,Python,Python 3.x,Multithreading,Multiprocessing,Pathos,实例不保留对属性的更改,甚至不保留已创建的新属性,这是我遇到的问题。我想我已经把范围缩小到这样一个事实,即我的脚本利用了多处理,并且我认为当脚本返回到主线程时,在单独的进程线程中发生的实例更改不会被“记住” 基本上,我有几组数据需要并行处理。数据作为属性存储,并通过类中的几个方法进行更改。在处理结束时,我希望返回到主线程并连接来自每个对象实例的数据。但是,如上所述,当我在并行处理位完成后尝试使用数据访问instance属性时,那里什么都没有。这就好像在多处理位期间执行的任何更改都被“遗忘” 有没

实例不保留对属性的更改,甚至不保留已创建的新属性,这是我遇到的问题。我想我已经把范围缩小到这样一个事实,即我的脚本利用了多处理,并且我认为当脚本返回到主线程时,在单独的进程线程中发生的实例更改不会被“记住”

基本上,我有几组数据需要并行处理。数据作为属性存储,并通过类中的几个方法进行更改。在处理结束时,我希望返回到主线程并连接来自每个对象实例的数据。但是,如上所述,当我在并行处理位完成后尝试使用数据访问instance属性时,那里什么都没有。这就好像在多处理位期间执行的任何更改都被“遗忘”

有没有一个明显的解决办法来解决这个问题?或者我需要重建代码来返回处理过的数据,而不是仅仅将其更改/存储为实例属性?我想另一种解决方案是序列化数据,然后在必要时重新读取,而不仅仅是将其保存在内存中

这里可能值得注意的是,我使用的是
pathos
模块,而不是python的
多处理
模块。我得到了一些关于酸洗的错误,类似于这里:。我的代码跨越几个模块,如前所述,数据处理方法包含在一个类中

对不起,这是文字墙

编辑 这是我的密码:

import importlib
import pandas as pd
from pathos.helpers import mp
from provider import Provider

# list of data providers ... length is arbitrary
operating_providers = ['dataprovider1', 'dataprovider2', 'dataprovider3']


# create provider objects for each operating provider
provider_obj_list = []
for name in operating_providers:
    loc     = 'providers.%s' % name
    module  = importlib.import_module(loc)
    provider_obj = Provider(module)
    provider_obj_list.append(provider_obj)

processes = []
for instance in provider_obj_list:
    process = mp.Process(target = instance.data_processing_func)
    process.daemon = True
    process.start()
    processes.append(process)

for process in processes:
    process.join()

# now that data_processing_func is complete for each set of data, 
# stack all the data
stack = pd.concat((instance.data for instance in provider_obj_list))
我有许多模块(它们的名称列在
操作\u提供者
中),它们包含特定于其数据源的属性。这些模块以迭代方式导入并传递给Provider类的新实例,我在一个单独的模块(
Provider
)中创建了Provider类。我将每个提供者实例附加到一个列表(
Provider\u obj\u list
),然后迭代创建单独的进程,这些进程调用实例方法
instance.data\u processing\u func
。此函数执行一些数据处理(每个实例访问完全不同的数据文件),并在此过程中创建新的实例属性,我需要在并行处理完成时访问这些属性

我尝试使用多线程,而不是多处理——在本例中,我的实例属性保持不变,这就是我想要的。然而,我不确定为什么会发生这种情况——我必须研究线程和多处理之间的区别


谢谢你的帮助

下面是一些示例代码,演示如何执行我在注释中概述的操作。我无法测试它,因为我没有安装
provider
pathos
,但它应该能让您很好地了解我的建议

import importlib
from pathos.helpers import mp
from provider import Provider

def process_data(loc):
    module  = importlib.import_module(loc)
    provider_obj = Provider(module)
    provider_obj.data_processing_func()


if __name__ == '__main__':

    # list of data providers ... length is arbitrary
    operating_providers = ['dataprovider1', 'dataprovider2', 'dataprovider3']

    # create list of provider locations for each operating provider
    provider_loc_list = []
    for name in operating_providers:
        loc = 'providers.%s' % name
        provider_loc_list.append(loc)

    processes = []
    for loc in provider_loc_list:
        process = mp.Process(target=process_data, args=(loc,))
        process.daemon = True
        process.start()
        processes.append(process)

    for process in processes:
        process.join()

在Python中,多处理创建了在不同内存空间中运行的子进程,但进程中的线程都在同一内存空间中执行。在进程之间共享数据涉及“酸洗”和将数据从一个进程发送到另一个进程(并在其中取消酸洗)。线程不需要这样做,但需要控制对共享数据的并发访问以防止损坏问题。你的问题中没有任何代码,这使得任何人都很难给你一个更具体的答案。谢谢@martineau!我用我的代码编辑了我的答案。我还使用
线程
实现了脚本。我将研究两者之间的区别。好的,这里有一个更具体的答案。我认为您得到pickle错误是因为您试图将
Provider
实例传递给子流程。一种解决方法是定义一个只接受单个
loc
参数的目标函数,然后该函数可以使用该参数加载所需的模块,从中创建一个
提供程序
实例,然后使用该实例调用其
数据处理函数()
。我是
pathos
(和
多进程
)作者我认为@martineau有一个很好的方法。一个线程池肯定可以工作。您还可以研究重构,以便使用共享内存数组(从
多进程
/
多进程
)。。。但这可能会导致比@martineau的答案更复杂的事情。在阅读了@Mike McKerns的评论后,我意识到我完全忽略了从子流程中获取数据的问题,部分原因是您在添加到问题中的示例代码中没有做任何明显的事情。根据所涉及的数据类型,我知道有几种可能性。至于这是否适合多线程,这取决于正在进行的“数据处理”类型。除非它是i/o绑定的,否则多处理可能会更快。