在进程之间共享具有文件句柄属性的对象

时间:2009-07-02 16:42:47

标签: python multiprocessing

我对进程间文件句柄的共享资源有疑问。 这是我的测试代码:

from multiprocessing import Process,Lock,freeze_support,Queue
import tempfile
#from cStringIO import StringIO

class File():
    def __init__(self):
        self.temp = tempfile.TemporaryFile()
        #print self.temp

    def read(self):
        print "reading!!!"
        s = "huanghao is a good boy !!"
        print >> self.temp,s
        self.temp.seek(0,0)

        f_content = self.temp.read()
        print f_content

class MyProcess(Process):
    def __init__(self,queue,*args,**kwargs):
        Process.__init__(self,*args,**kwargs)
        self.queue = queue

    def run(self):
        print "ready to get the file object"
        self.queue.get().read()
        print "file object got"
        file.read()

if __name__ == "__main__":
    freeze_support()
    queue = Queue()
    file = File()

    queue.put(file)
    print "file just put"

    p = MyProcess(queue)
    p.start()

然后我得到如下KeyError

file just put
ready to get the file object
Process MyProcess-1:
Traceback (most recent call last):
  File "D:\Python26\lib\multiprocessing\process.py", line 231, in _bootstrap
    self.run()
  File "E:\tmp\mpt.py", line 35, in run
    self.queue.get().read()
  File "D:\Python26\lib\multiprocessing\queues.py", line 91, in get
    res = self._recv()
  File "D:\Python26\lib\tempfile.py", line 375, in __getattr__
    file = self.__dict__['file']
KeyError: 'file'

我认为当我将File()对象放入队列时,对象被序列化,文件句柄无法序列化,因此,我得到了KeyError

有人对此有任何想法吗?如果我想与文件句柄属性共享对象,我该怎么办?

1 个答案:

答案 0 :(得分:7)

我必须反对(最后,不仅仅适用于评论;-) @ Mark的重复断言,文件句柄不能“在正在运行的进程之间传递” - 这根本不是真的真实的,现代化的操作系统,比如,哦,比方说,Unix(免费的BSD变种,MacOSX和Linux,包括 - 嗯,我想知道什么操作系统被排除在这个列表之外......? - ) - {{3当然可以这样做(在“Unix套接字”上,使用SCM_RIGHTS标志)。

现在,穷人,有价值的multiprocessing完全没有利用这个功能(即使假设在Windows上也可能有黑魔法) - 大多数开发人员无疑会滥用它(有多个进程)同时访问相同的打开文件并进入竞争条件)。使用它的唯一正确方法是具有独占权限的进程,该进程具有打开某些文件以将打开的文件句柄传递给另一个以降低的权限运行的进程的权限 - 然后再也不会使用该句柄本身。无论如何,无法在multiprocessing模块中强制执行此操作。

回到@Andy的原始问题,除非他只在Linux上工作(并且只使用本地进程)并且愿意使用/ proc文件系统玩弄脏技巧,否则他将不得不定义他的应用程序级需求更严格地并相应地序列化file个对象。大多数文件都有一个路径(或者可以有一个路径:无路径文件非常罕见,在我认为的Windows上实际上不存在)因此可以通过它进行序列化 - 许多其他文件都很小,可以通过发送它们来序列化内容超过等等。