2009-07-02 12 views
5

プロセス間のファイルハンドルで共有リソースに関する質問があります。ここ は私のテストコードです:プロセス間のファイルハンドル属性を持つオブジェクトを共有する

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を持っています:

誰でも知っている?ファイルハンドル属性でオブジェクトを共有したい場合、どうすればよいですか?

答えて

7

ファイルハンドルが「実行中のプロセス間でやりとりできない」という@Markの繰り返しの主張に、私は長すぎるにもかかわらず、コメントする必要はありません.--これは単に真実ではありませんUnix(フリーBSDの亜種、MacOSX、Linuxなど、現実的で現代的なオペレーティングシステムでは - hmmm、このリストの中に残っているOSは何か...?) - ) - sendmsgコースはそれを行うことができます(SCM_RIGHTSフラグを使って "Unix socket"で)。

multiprocessingは、この機能を悪用しないように完全に正しいです(Windowsでも実装するには黒い魔法があると仮定しています)。大抵の開発者は、ファイルを同時に開き、競合状態に陥る)。それを使用する唯一の正しい方法は、特定のファイルを開いて、開いたファイルハンドルを特権のない別のプロセスに渡す排他的な権利を持つプロセスのことです。とにかくmultiprocessingモジュールでそれを強制する方法はありません。

@ Andyのオリジナルの質問に戻ると、彼はLinuxだけで(そしてローカルプロセスだけでも)作業し、/ procファイルシステムで汚い技を喜んでプレイしない限り、彼はアプリケーションレベルを定義しなければなりませんより急激に必要とし、それに応じてfileオブジェクトをシリアル化します。ほとんどのファイルはパスを持っています(パスレスファイルは非常にまれですが、実際には存在しないと私は思っています)、それを介してシリアライズすることができます。コンテンツオーバー - 等

+0

私は、少なくとも2番目の修正を行うことを意味していたと思うファイル*ディスクリプタ* - ここでは、一般的に数字> = 3(0,1、 2はstd {in、out、err}のために予約されています)。したがって、ファイルを開いてディスクリプタが3の場合、3を別のプロセスに渡すことは無意味です。私は最終的にそこにヒットしましたか? –

+0

ありがとう、アレックス!だから、あなたが言ったように、私はウィンドウ上のプロセス間でファイルハンドルを渡したい場合は非常に難しいです。私はファイルを渡す場合は、私は、ファイルのパスやファイルの内容ではなく、ファイルハンドルを渡す必要があります。 – Ryan

+0

@マーク、実際には、あなたが渡す必要があるのは実際には '3 'です... AF_UNIXソケットとSCM_RIGHTSフラグだけです(カーネルは必要な魔法の残りの部分を行います: = 3でも同じオープンファイルの記述子になります)。私が正しくリコールすれば、Solarisはより洗練された方法で、問題を正しく処理するために実際にはいくつかのシステムコールがあります(ただし、実際にはSolarisで作業してからあまりにも長くなりました。 –

関連する問題