编写并行编程框架,我遗漏了什么?
说明:根据一些评论,我需要澄清一下,这个框架是为了执行那些自然可以并行运行的程序(也就是所谓的“尴尬并行程序”)。它并不是,也永远不会是,解决需要进程之间通信或同步的任务的方案。
我一直在寻找一个简单的基于进程的并行编程环境,能够在集群的多个CPU上执行一个函数,主要的要求是能够执行不需要修改的Python代码。我找到的最接近的东西是Parallel Python,但它做了一些比较奇怪的事情,这可能导致代码在不正确的上下文中执行(比如没有导入合适的模块等)。
最后我厌倦了寻找,所以决定自己写一个。我想出来的其实很简单。问题是,我不确定我想出来的东西是否真的简单,可能是因为我没有考虑到很多事情。我的程序做了以下几件事:
- 我有一个工作服务器,它把工作分配给集群中的节点。
工作是通过传递一个字典分配给监听节点的服务器,这个字典看起来像这样:
{ 'moduleName':'some_module', 'funcName':'someFunction', 'localVars': {'someVar':someVal,...}, 'globalVars':{'someOtherVar':someOtherVal,...}, 'modulePath':'/a/path/to/a/directory', 'customPathHasPriority':aBoolean, 'args':(arg1,arg2,...), 'kwargs':{'kw1':val1, 'kw2':val2,...} }
moduleName
和funcName
是必须的,其他的都是可选的。一个节点服务器接收这个字典后会执行:
sys.path.append(modulePath) globals()[moduleName]=__import__(moduleName, localVars, globalVars) returnVal = globals()[moduleName].__dict__[funcName](*args, **kwargs)
得到返回值后,服务器会把它发送回工作服务器,工作服务器会把结果放入一个线程安全的队列中。
- 当最后一个工作返回时,工作服务器会把输出写入文件并退出。
我相信还有一些小问题需要解决,但这个方法有没有明显的错误呢?乍一看,它似乎很稳健,只需要节点能够访问包含.py文件和依赖项的文件系统。使用__import__
的好处是模块中的代码会自动运行,因此函数应该在正确的上下文中执行。
任何建议或批评都将非常感谢。
编辑:我应该提到,我已经让代码执行部分工作了,但服务器和工作服务器还没有写好。
2 个回答
我自己一直在尝试在不同的电脑上批量处理图片,最大的问题就是有些东西不能直接保存和通过网络传输。
比如说:pygame的表面(surfaces)不能直接保存。我需要把它们转换成字符串,先保存在StringIO对象里,然后再通过网络发送。
如果你要传输的数据(比如你的参数)是可以安全传输的,那你在网络数据方面就不会遇到太多问题。
还有一个问题:如果在执行任务的时候,有一台电脑突然“消失”了,你打算怎么办?在返回数据的时候呢?你有没有计划重新发送任务?
其实我写了一个可能能满足你需求的东西:jug。如果它不能解决你的问题,我保证会修复你发现的任何错误。
这个系统的架构稍微有点不同:所有的工作者都运行相同的代码,但它们实际上会生成一个类似的字典,并询问中央后台“这个任务有没有被执行过?”如果没有,它们就会执行这个任务(这里还有一个锁定机制)。如果你是在NFS系统上,后台可以简单地用文件系统来实现。