如何在不使用多个进程的情况下将 python 对象保留在 RAM 中?



我正在使用一个我无法控制的外部程序,该程序在某些时候调用我可以指定的子进程,传递一些参数并在完成后检查其退出状态。

我希望这个程序调用的子进程是一个执行一些计算的python 3脚本 使用构造成本非常高且非常大的对象。因为对象的构造非常昂贵,我不想每次外部程序调用脚本时都构造它,并且因为它占用了相当多的空间,所以每次都将其腌制到磁盘并加载它很慢。

我目前的解决方案是有两个进程,其中一个构造对象并在请求时执行计算,另一个进程由外部程序调用,其唯一真正目标是通过套接字与第一个进程通信并要求它执行其任务。

第一个进程的代码大致如下所示:

# process1.py, performs calculations
import socket
import pickle
def do_expensive_calculations(large_object, data):
# some expensive calculations
return value
class LargeAndSlow:
def __init__(self):
# some code
if __name__ == '__main__':
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.bind('ADDRESS')
s.listen(1)

large_object = LargeAndSlow()
while True: 
(conn, address) = s.accept()
data = pickle.loads(conn.recv(4096))
value = do_expensive_calculations(large_object, data)
conn.send(pickle.dumps(value))

第二个(外部程序调用的那个(像这样:

# process2.py
import sys
import socket
import pickle
def value_is_correct(value):
# check if value is correct
return is_correct
if __name__ == '__main__':
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect('ADDRESS')
s.send(pickle.dumps(sys.argv))

value = pickle.loads(s.recv(4096))
if value_is_correct(value):
s.close()
sys.exit(0)
else:
s.close()
sys.exit(1)

然而,这个解决方案实际上比每次都构造对象要慢,我怀疑这是由于同时运行多个 python 进程并通过 UNIX 套接字进行通信的开销(但是,我可能是错的,也许我只是以一种非常低效的方式编码(。

有没有更快、更有效的解决这个问题的方法?

您可以创建一个 RAM 磁盘分区并将其挂载为常规文件系统。在Unix系统上,您可以使用tmpfs来实现此目的。

从程序的角度来看,您的文件看起来像一个普通文件。不过,操作系统会将其存储在内存中。

请记住,您可能会(或可能不会(注意到的速度改进将取决于许多因素。I/O可能是其中之一,tmpfs会有所帮助。然而,瓶颈可能是其他原因,例如酸洗/脱洗过程。

如果你使用的是Python 3.8,Python的多处理库已经支持SharedMemory类。它可以让多个进程直接访问同一个内存区域。因此,在不同进程中移动大型对象不会产生开销。您可以参考 Python 的文档以获取更多详细信息。

如果你没有使用Python 3.8,有一个Python包SharedArray,它具有类似的功能。

最新更新