Делитесь объектами с атрибутом дескриптора файла между процессами

StackOverflow https://stackoverflow.com/questions/1075443

  •  21-08-2019
  •  | 
  •  

Вопрос

У меня вопрос об общем ресурсе с дескриптором файла между процессами.Вот мой тестовый код:

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:

Кто-нибудь имеет какое-либо представление об этом?если я хочу поделиться объектами с атрибутом дескриптора файла, что мне делать?

Это было полезно?

Решение

Я должен возразить (в конце концов, это не просто комментарий;-) против неоднократного утверждения @Mark о том, что дескрипторы файлов просто не могут «передаваться между запущенными процессами» - это просто не соответствует действительности в реальных, современных операционные системы, такие как, скажем, Unix (включая бесплатные варианты BSD, MacOSX и Linux — хммм, интересно, какие ОС не включены в этот список...?-) — отправить сообщение конечно, можно это сделать (в «Unix-сокете», используя команду SCM_RIGHTS флаг).

Теперь бедный, ценный multiprocessing совершенно правильно не использовать эту функцию (даже если предположить, что для ее реализации в Windows может быть использована черная магия) - большинство разработчиков, несомненно, в любом случае будут злоупотреблять ею (при одновременном доступе нескольких процессов к одному и тому же открытому файлу и возникновении условий гонки).Единственный правильный способ его использования — это чтобы процесс, имеющий исключительные права на открытие определенных файлов, передавал дескрипторы открытых файлов другому процессу, который работает с ограниченными привилегиями, а затем никогда больше не использовал этот дескриптор.Нет возможности обеспечить соблюдение этого в multiprocessing модуль, во всяком случае.

Возвращаясь к исходному вопросу @Andy, если только он не собирается работать только с Linux (И только с локальными процессами) и не хочет пакостить файловой системой /proc, ему придется более четко определить свои потребности на уровне приложения и сериализовать file объекты соответственно.У большинства файлов есть путь (или его можно создать так:файлы без пути довольно редки, я считаю, что их вообще нет в Windows) и, следовательно, их можно сериализовать через него - многие другие достаточно малы, чтобы их можно было сериализовать путем отправки их содержимого - и т. д. и т. п.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top