【问题标题】:Share objects with file handle attribute between processes在进程之间共享具有文件句柄属性的对象
【发布时间】:2009-07-02 16:42:46
【问题描述】:

我有一个关于进程间文件句柄共享资源的问题。 这是我的测试代码:

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

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

【问题讨论】:

    标签: python multiprocessing


    【解决方案1】:

    我必须反对(最终,不会只适合注释;-)@Mark 反复断言文件句柄不能“在正在运行的进程之间传递”——这在真正的现代操作系统,比如,哦,比如说,Unix(包括免费的 BSD 变体、MacOSX 和 Linux——嗯,我想知道哪些操作系统不在此列表中……?-)——sendmsg当然可以(在“Unix 套接字”上,使用SCM_RIGHTS 标志)。

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

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

    【讨论】:

    • 我想我想说的(至少是第二次更正)是文件 descriptor - 你通常会得到一个 >= 3 的数字(由于 0, 1,2 为 std{in,out,err} 保留)。因此,如果您打开一个文件并且它的描述符是 3,那么将 3 传递给另一个进程是没有意义的。我终于打到那里了吗?
    • 非常感谢,亚历克斯!所以,正如你所说,如果我想在 Windows 上的进程之间传递文件句柄是非常困难的。如果我想传递文件,我应该传递文件路径或文件内容,而不是文件句柄。
    • @Mark,不是真的,它确实是你需要传递的3... 只是在一个 AF_UNIX 套接字和 SCM_RIGHTS 标志上(内核将完成其余所需的魔法:到达的数字可能是!= 3,但它将是同一个打开文件的描述符)。如果我没记错的话,Solaris 有一个更简洁的方法,实际上有几个系统调用来正确处理这个问题(但是自从我真正在 Solaris 上工作已经太久了,叹息,我记不太清了)。
    • @Andy,是的,你完美地总结了它的要点——文件路径很简单,文件内容很简单,打开文件的句柄太难了(而且我太生疏了一位 Win32 大师,甚至尝试“从深渊召唤那些灵魂”;-)。
    猜你喜欢
    • 1970-01-01
    • 2010-09-13
    • 2013-06-04
    • 2012-07-22
    • 1970-01-01
    • 2021-11-11
    • 2021-10-21
    • 2016-02-05
    • 1970-01-01
    相关资源
    最近更新 更多