简体   繁体   English

具有共享库和内存持久性的Python多处理

[英]Python multiprocessing with shared library and memory persistance

I am using Python as a driver to run thousands of numerical simulations. 我使用Python作为驱动程序来运行数千个数值模拟。 Since the initialization procedure for each simulation is the same, I can save time by doing the (time-consuming) initialisation procedure once, backup in memory the initial state of the vectors and for each subsequent simulation simply restore those vectors. 由于每个模拟的初始化过程是相同的,因此我可以通过执行一次(耗时的)初始化过程来节省时间,将向量的初始状态备份到内存中,并且对于每个后续的模拟只需恢复这些向量即可。

A small working example is: 一个小的工作示例是:

from ctypes import cdll

try:
    lib = cdll.LoadLibrary('shared_lib.so')
    print lib.set_to_backup() # this tells the program to save the initial state
    print lib.simulate("cmd.txt") # initializes, backs up state, saves an internal variable -backed_up- to true and simulates
    print lib.simulate("cmd2.txt") # sees the internal state -backed_up- equal to true and skips initialisation, restores from memory and simulates
except:
    import traceback
    traceback.print_exc()

This works perfectly and I can run several simulations (cmd1, cmd2, ...) without reinitializing. 这可以完美运行,并且我可以运行多个模拟(cmd1,cmd2等)而无需重新初始化。

Now, I want to parallelize this procedure using multiprocessing. 现在,我想使用多处理并行化此过程。 So, each process should load the library once and run the first simulation with initializing, saving and simulating. 因此,每个进程应加载一次库并运行初始化,保存和模拟的第一个模拟。 Each subsequent simulation should reload the initial state and simulate. 随后的每个模拟都应重新加载初始状态并进行模拟。 The example for one process: 一个过程的示例:

from ctypes import cdll
from multiprocessing import Process

try:
    lib = cdll.LoadLibrary('shared_lib.so')
    print lib.set_to_backup() # this tells the program to save the initial state
    p1 = Process(target=lib.simulate, args=("cmd.txt",)) # initializes, backs up state, saves an internal variable -backed_up- to true and simulates
    p1.start()
    p1.join()
    print p1.exitcode

    p2 = Process(target=lib.simulate, args=("cmd2.txt",)) # (should) see the internal state -backed_up- equal to true and skips initialisation, restores from memory and simulates
    p2.start()
    p2.join()
    print p2.exitcode
except:
    import traceback
    traceback.print_exc()

The first process does the job correctly (I can see it in the trace). 第一个过程正确完成了工作(我可以在跟踪中看到它)。 The second process doesn't see the -backed_up- variable in lib and re-initialises everything. 第二个过程在lib中看不到-backed_up-变量,并重新初始化所有内容。

I tried without declaring a new process, but simply reruning p1.start() to restart the same process but it fails (assert self._popen is None, 'cannot start a process twice'). 我尝试了不声明新进程的情况,只是重新运行p1.start()以重新启动同一进程,但失败了(断言self._popen为None,“无法两次启动进程”)。

-backed_up- is a global variable in lib and should remain in memory between calls to lib.simulate (as it does in the first example). -backed_up-是lib中的全局变量,应该在两次调用lib.simulate之间保留在内存中(与第一个示例一样)。

I run Linux Debian 7 and use python 2.7.3. 我运行Linux Debian 7并使用python 2.7.3。

Anyone has an idea how to make this work please? 任何人都有一个想法如何使这项工作吗?

I managed to get it to work using a queue. 我设法使它使用队列工作。 Answer heavily inspired by --> https://stackoverflow.com/a/6672593/801468 受-> https://stackoverflow.com/a/6672593/801468启发的答案

import multiprocessing
from ctypes import cdll

num_procs = 2

def worker():
    lib = cdll.LoadLibrary('shared_lib.so')
    print lib.set_to_backup()
    for DST in iter( q.get, None ):
        print 'treating: ', DST
        print lib.simulate(DST)
        q.task_done()
    q.task_done()

q = multiprocessing.JoinableQueue()
procs = []
for i in range(num_procs):
    procs.append( multiprocessing.Process(target=worker) )
    procs[-1].daemon = True
    procs[-1].start()

list_of_DST = ["cmd1.txt", "cmd2.txt"]
for DST in list_of_DST:
    q.put(DST)

q.join()

for p in procs:
    q.put( None )

q.join()

for p in procs:
    p.join()

print "Finished everything...."
print "Active children:", multiprocessing.active_children()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM