Pregunta

Tengo una pregunta acerca de los recursos compartidos con identificador de archivo entre los procesos. Aquí está mi código de prueba:

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()

Entonces consigo un KeyError, como a continuación:

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'

Creo que cuando pongo el File() objeto en la cola, el objeto serializado consiguió, y identificador de archivo no se puede serializar, por lo que, tengo el <=>:

Alguien tiene alguna idea acerca de eso? si quiero compartir objetos con el atributo identificador de archivo, ¿qué debería hacer?

¿Fue útil?

Solución

Yo no tengo que objetar (a la distancia, a sólo en forma de una commentl ;-) @ a la reiterada afirmación de Mark archivo que maneja simplemente no puede ser "pasa alrededor entre procesos en ejecución" - esto simplemente no es cierto en sistemas operativos reales, modernas, tales como, oh, digamos, Unix (BSD variantes libre, MacOSX y Linux, incluida - Hmmm, me pregunto qué sistemas operativos están dejado fuera de esta lista ... -?) - sendmsg por supuesto puede hacerlo (en un "socket de Unix", mediante el uso de la SCM_RIGHTS bandera).

Ahora los pobres, multiprocessing valioso es totalmente derecho a no explotar esta característica (aun suponiendo que puede haber magia negro ponerlo en práctica también en Windows) - la mayoría de los desarrolladores, sin duda, sería un mal uso de todos modos (que tienen múltiples procesos de acceso a la mismo archivo al mismo tiempo abierta y en funcionamiento en condiciones de carrera). La única forma correcta de usarlo es un proceso que tiene los derechos exclusivos para abrir ciertos archivos para pasar el archivo abierto maneja a otro proceso que se ejecuta con privilegios reducidos - y luego nunca uso que manejarse de nuevo. No hay manera de que lo imponen en el file módulo, de todos modos.

Volver a @ pregunta original de Andy, a menos que él va a trabajar solo en Linux (Y con los procesos locales solamente, también) y dispuesto a jugar malas pasadas con el sistema de archivos / proc, que va a tener que definir sus necesidades a nivel de aplicación más bruscamente y serializar objetos <=> en consecuencia. La mayoría de los archivos tienen un camino (o se pueden hacer para tener uno: ficheros de camino-menos son bastante raro, en realidad no existe en Windows creo) y por lo tanto pueden ser serializados a través de él - muchos otros son lo suficientemente pequeños para serializar mediante el envío de su contenido a través de -. etc, etc

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top