什么是守护进程?为什么要创建它?



我正在尝试将字符串转换为日期时间对象。这些字符串存储在 csv 列中。文件很大,我想多处理它。

我的代码看起来像这样:

def conv_datetime(file):
return ([pd.to_datetime(j[3]) for j in file])
if __name__ == "__main__":
n = 0
file = pd.read_csv("csv_file",header=None,chunksize=200,skiprows=n)
n += 200
pro = mp.Process(target=conv_datetime,args=(file,))
pro.deamon = False
pro.start()
pro.join()

我得到 :

AttributeError     
Traceback (most recent call last)
<ipython-input-1-5d16d82af0d2> in <module>()
15     pro = mp.Process(target=conv_datetime,args=(file,))
16     pro.deamon = False
---> 17     pro.start()
18     pro.join()
19 
C:ProgramDataAnaconda33libmultiprocessingprocess.py in start(self)
103                'daemonic processes are not allowed to have children'
104         _cleanup()
--> 105         self._popen = self._Popen(self)
106         self._sentinel = self._popen.sentinel
107         # Avoid a refcycle if the target function holds an indirect
C:ProgramDataAnaconda33libmultiprocessingcontext.py in _    Popen(process_obj)
221     @staticmethod
222     def _Popen(process_obj):
--> 223         return  _default_context.get_context().Process._Popen(process_obj)
224 
225 class DefaultContext(BaseContext):
C:ProgramDataAnaconda33libmultiprocessingcontext.py in _Popen(process_obj)
320         def _Popen(process_obj):
321             from .popen_spawn_win32 import Popen
--> 322             return Popen(process_obj)
323 
324     class SpawnContext(BaseContext):
C:ProgramDataAnaconda33libmultiprocessingpopen_spawn_win32.py in __init__(self, process_obj)
63             try:
64                 reduction.dump(prep_data, to_child)
---> 65                 reduction.dump(process_obj, to_child)
66             finally:
67                 set_spawning_popen(None)
C:ProgramDataAnaconda33libmultiprocessingreduction.py in dump(obj, file, protocol)
58 def dump(obj, file, protocol=None):
59     '''Replacement for pickle.dump() using ForkingPickler.'''
---> 60     ForkingPickler(file, protocol).dump(obj)
61 
62 #
AttributeError: Can't pickle local object '_make_date_converter.<locals>.converter'

在有人给我代码解决方案之前,如果可以深入了解守护进程的工作原理,那将非常有帮助。

如果你看一下multiprocessing/process.py代码(你似乎没有使用Python 3.6,所以行号有点不同,但这部分代码是不变的),你可以很清楚地看到关于守护进程的字符串是不相关的; 这只是您的代码设法通过而没有任何问题的assert的一部分, 在几行之后由于完全不相关的原因失败之前。


实际问题出在第 105 行,错误消息中对此进行了说明:

AttributeError: Can't pickle local object '_make_date_converter.<locals>.converter'

您正在尝试将对象传递给无法酸洗的子进程。这在multiprocessing文档中进行了一些解释,例如,在编程指南下,尽管这些文档假设您理解"pickle"的含义,并且您已经阅读了文档的相当多的早期部分。您确实应该阅读前面的部分,并在文档中查找pickle,但基本思想是这样的:

multiprocessing模块使用pickle模块将参数传递给函数、从函数返回值、将值放在队列中等。pickle模块只能处理设计为可选取的数据类型。因此,某些类型不能与multiprocessing一起传递。

在这种情况下,应该有一个非常简单的解决方法:只需传递文件名,然后让子进程读取它。当然,这不适用于更复杂的情况,但如果它适用于您的情况,请保持简单。

对于更复杂的情况,Pandas 的通常解决方案是用第三方库(如dillcloudpickle)替换标准拾取器,这些库更了解 Pandas 并可以强制其成形以通过网络。(或者,有时,将multiprocess本身替换为第三方库,如dask。这并不难学,但你确实需要查看选项,选择一个,并阅读如何挂钩它,如果不需要,你可能不想这样做。


如果您仍然对守护进程感兴趣,请参阅参考文档中的进程。但简短的版本是,在这种情况下,守护进程是一个不被join编辑的进程 - 换句话说,你不会像普通进程那样等待它在主进程完成时完成。

相关内容

  • 没有找到相关文章

最新更新