multiprocessing.Pool
,它在一个或多个子进程中调用一个函数来生成大量数据。multiprocessing.shared_memory.SharedMemory
对象,并使用shared_memory
分配的默认名称。SharedMemory
对象的字符串名称返回给主进程。SharedMemory
对象被链接、使用,然后是未链接和关闭的。关机时我看到resource_tracker
发出的警告
/usr/local/lib/python3.8/multiprocessing/resource_tracker.py:216: UserWarning: resource_tracker: There appear to be 10 leaked shared_memory objects to clean up at shutdown
warnings.warn('resource_tracker: There appear to be %d '
/usr/local/lib/python3.8/multiprocessing/resource_tracker.py:229: UserWarning: resource_tracker: '/psm_e27e5f9e': [Errno 2] No such file or directory: '/psm_e27e5f9e'
warnings.warn('resource_tracker: %r: %s' % (name, e))
/usr/local/lib/python3.8/multiprocessing/resource_tracker.py:229: UserWarning: resource_tracker: '/psm_2cf099ac': [Errno 2] No such file or directory: '/psm_2cf099ac'
<8 more similar messages omitted>
由于我在主进程中断开了共享内存对象的链接,所以我对这里发生的事情感到困惑。我怀疑这些消息发生在子流程中(在本例中,我用一个大小为1的进程池进行了测试)。
下面是一个最低可重现性的例子:
import multiprocessing
import multiprocessing.shared_memory as shared_memory
def create_shm():
shm = shared_memory.SharedMemory(create=True, size=30000000)
shm.close()
return shm.name
def main():
pool = multiprocessing.Pool(processes=4)
tasks = [pool.apply_async(create_shm) for _ in range(200)]
for task in tasks:
name = task.get()
print('Getting {}'.format(name))
shm = shared_memory.SharedMemory(name=name, create=False)
shm.close()
shm.unlink()
pool.terminate()
pool.join()
if __name__ == '__main__':
main()
我发现在我自己的笔记本电脑(LinuxMint19.3)上运行这个示例很好,但是在两台不同的服务器机器上运行它(未知的OS配置,但都不同)确实显示了问题。在所有情况下,我都是从docker容器运行代码的,因此Python/software配置是相同的,唯一的区别是Linux内核/主机操作系统。
我注意到以下可能相关的文档:https://docs.python.org/3.8/library/multiprocessing.html#contexts-and-start-methods
我还注意到,“泄漏的shared_memory对象”的数量因运行而异。由于我在主进程中断开链接,然后立即退出,也许这个resource_tracker
(我认为它是一个单独的进程)在主进程退出之前还没有收到更新。不过,我不太了解resource_tracker
的作用,无法完全理解我刚才提出的建议。
相关专题:
发布于 2022-06-27 13:07:35
我的工作也有类似的地方。我有几个微服务运行在不同的控制台中,因此在不同的进程中运行。
为了消除警告,我在每个微服务中创建共享内存名称时注册它。
然后当关闭微型服务时
for shared_name in self.shared_memory_list_toclean:
sm_temp = sm.SharedMemory(name=shared_name)
sm_temp.close()
sm_temp.unlink()
因为每个进程负责共享内存的断开连接。
编辑:事实上,当进程使用共享内存时,我仍然有警告的问题(enven,如果没有创建它)。我用Diego在https://bugs.python.org/issue39959中提出的解决方案解决了这个问题
我所做的是复制文件shared_memory.py从多处理在我的回购。并提出了解决办法:
顶替
from .resource_tracker import register
register(self._name, "shared_memory")
在第119行
if create:
from multiprocessing.resource_tracker import register
register(self._name, "shared_memory")
然后在我的代码中使用共享内存,而不是导入:
from multiprocessing import shared_memory as sm
我会这样做:
import my_sharedmemory as sm
https://stackoverflow.com/questions/62748654
复制相似问题