[pyar] os.dup(), threads y os.read()

Claudio Freire klaussfreire en gmail.com
Mar Dic 1 20:29:35 ART 2015


2015-12-01 19:59 GMT-03:00 Marcos Dione <mdione en grulic.org.ar>:
> # acá aprieto enter y pasa esto:
> In [16]: Exception in thread Thread-3:
> Traceback (most recent call last):
>   File "/usr/lib/python3.4/threading.py", line 911, in _bootstrap_inner
>     self.run()
>   File "/usr/lib/python3.4/threading.py", line 859, in run
>     self._target(*self._args, **self._kwargs)
>   File "<ipython-input-12-94b37b63f852>", line 3, in foo
>     d= os.read (f, 1024)
> OSError: [Errno 9] Bad file descriptor
> --- >8 ---
>
>     o sea, el os.dup() me devuelva un fd que apunta al mismo file que 0
> (stdin, por si no se dieron cuenta). lo que parece pasar es que os.read()
> blockea esperando data, y cuando cierro el fd, *no pasa nada*. lo que yo
> esperaría es que el read() del loop vea el EOF y devuelva ''. es muy
> delirante pedir eso? sino, es un bug? si lo es, muy probablemente sea un
> bug en el kernel, pero no me he sentado a ver aún.


Pero lo que hiciste no es cerrar el lado del pipe que escribe en
stdin, sino cerrar el lado que lee.

Así que intentar leer de un fd cerrado es exactamente un "Bad file descriptor".

El lado del pipe de stdin que querés cerrar lamentablemente no está
bajo tu control, así que no lo podés cerrar.

Lo que deberías hacer, que, sí, es medio una goma, es usar dos fd en
el thread, stdin, y un pipe:

f = os.dup(0)
rwake, wwake = os.pipe()
fcntl.fcntl(f, fcntl.F_SETFL, fcntl.fcntl(f, fcntl.F_GETFL) | os.O_NONBLOCK)
def foo(f, wake):
    r,w,x = select.select([f,wake], [], [f,wake])
    if wake in r:
        break
    if f in r:
        d = os.read(f, 1024)
os.write(wake, 'w')

O algo así (no lo probé, pero esa es la idea)


More information about the pyar mailing list