Problemas extraños al usar solicitudes y multiprocesamiento

Por favor, compruebe este código de Python:

#!/usr/bin/env python
import requests
import multiprocessing
from time import sleep, time
from requests import async

def do_req():
    r = requests.get("http://w3c.org/")

def do_sth():    
    while True:
        sleep(10)

if __name__ == '__main__':        
    do_req()
    multiprocessing.Process( target=do_sth, args=() ).start()

Cuando presiono Ctrl-C (espere 2 segundos después de ejecutar, deje que se ejecute el proceso), no se detiene. Cuando cambio el orden de importación a:

from requests import async
from time import sleep, time

se detiene después de Ctrl-C. ¿Por qué no se detiene/mata en el primer ejemplo?

¿Es un error o una característica?

Notas

  • Sí, lo sé, no usé async en este código, solo es un código simplificado. En código real lo uso. Lo hice para simplificar mi pregunta.
  • Después de presionar Ctrl-C, se está ejecutando un nuevo proceso (secundario). ¿Por qué?
  • multiprocessing.__version__ == 0.70a1, requests.__version__ == 0.11.2, gevent.__version__ == 0.13.7

preguntado el 03 de mayo de 12 a las 21:05

tal vez sobrescriba algunos módulos o nombres de funciones (¿tiempo?). Intente dejar de usar "from .. import .." y use nombres completos como "time.time()", tal vez esto resuelva su problema (no lo intenté yo mismo) -

1 Respuestas

El módulo asíncrono de solicitudes utiliza gevent. Si miras el código fuente de gevent verás que parches de mono muchas de las funciones de la biblioteca estándar de Python, incluida la suspensión:

módulo request.async durante las ejecuciones de importación:

    from gevent import monkey as curious_george
    # Monkey-patch.
    curious_george.patch_all(thread=False, select=False)

Mirando el módulo monkey.py de gevent puedes ver:

https://bitbucket.org/denis/gevent/src/f838056c793d/gevent/monkey.py#cl-128

def patch_time():
    """Replace :func:`time.sleep` with :func:`gevent.sleep`."""
    from gevent.hub import sleep
    import time
    patch_item(time, 'sleep', sleep)

Eche un vistazo al código del repositorio de gevent para obtener más detalles.

contestado el 04 de mayo de 12 a las 11:05

Sí, acabo de llegar a ese código también. Y dado que @neutrinus importa el sueño desde el tiempo antes de importar asíncrono en el caso 1, se perderá ese parche siempre que use el sueño en lugar de time.sleep - snies

Gracias por una explicación completa. Como parece un problema con el parcheo de gevent... Actualicé a la versión 1.0 de gevent y funcionó (se trasladaron a libev en lugar de libevent). Esta versión debería estar en pypi por cierto... - neutrino

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.