Python 实例属性不会使用多处理持久化
实例不保留对属性的更改,甚至不保留已创建的新属性,这是我遇到的问题。我想我已经把范围缩小到这样一个事实,即我的脚本利用了多处理,并且我认为当脚本返回到主线程时,在单独的进程线程中发生的实例更改不会被“记住” 基本上,我有几组数据需要并行处理。数据作为属性存储,并通过类中的几个方法进行更改。在处理结束时,我希望返回到主线程并连接来自每个对象实例的数据。但是,如上所述,当我在并行处理位完成后尝试使用数据访问instance属性时,那里什么都没有。这就好像在多处理位期间执行的任何更改都被“遗忘” 有没有一个明显的解决办法来解决这个问题?或者我需要重建代码来返回处理过的数据,而不是仅仅将其更改/存储为实例属性?我想另一种解决方案是序列化数据,然后在必要时重新读取,而不仅仅是将其保存在内存中 这里可能值得注意的是,我使用的是Python 实例属性不会使用多处理持久化,python,python-3.x,multithreading,multiprocessing,pathos,Python,Python 3.x,Multithreading,Multiprocessing,Pathos,实例不保留对属性的更改,甚至不保留已创建的新属性,这是我遇到的问题。我想我已经把范围缩小到这样一个事实,即我的脚本利用了多处理,并且我认为当脚本返回到主线程时,在单独的进程线程中发生的实例更改不会被“记住” 基本上,我有几组数据需要并行处理。数据作为属性存储,并通过类中的几个方法进行更改。在处理结束时,我希望返回到主线程并连接来自每个对象实例的数据。但是,如上所述,当我在并行处理位完成后尝试使用数据访问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绑定的,否则多处理可能会更快。