2011-04-28 14 views
19

Estoy buscando información sobre seguridad de subprocesos de urllib2 y httplib. La documentación oficial (http://docs.python.org/library/urllib2.html y http://docs.python.org/library/httplib.html) carece de información sobre este tema; la palabra hilo ni siquiera se menciona allí ...¿Son seguros los subprocesos urllib2 y httplib?

ACTUALIZACIÓN

Ok, no están seguro para subprocesos fuera de la caja. ¿Qué se necesita para que sean seguros para subprocesos o existe un escenario en el que pueden ser seguros para subprocesos? estoy pidiendo porque es parece que

  • usando separada OpenerDirector en cada hilo
  • no compartir conexión HTTP entre hilos

sería suficiente para utilizar con seguridad estas bibliotecas en las discusiones. escenario de uso similar fue propuesta en cuestión urllib2 and cookielib thread safety

Respuesta

40

httplib y urllib2 son no flujos seguros.

urllib2 no proporciona acceso a un número de serie (compartido) OpenerDirector objeto global, que es utilizado por urllib2.urlopen().

De forma similar, httplib no proporciona acceso serializado a los objetos HTTPConnection (es decir, mediante el uso de un grupo de conexiones de seguridad de subprocesos), por lo que compartir objetos HTTPConnection entre subprocesos no es seguro.

Sugiero usar httplib2 o urllib3 como alternativa si se requiere seguridad de hilos.

Generalmente, si la documentación de un módulo no menciona la seguridad de la hebra, supongo que no es seguro para subprocesos. Puede ver el código fuente del módulo para la verificación.

Al navegar por el código fuente para determinar si un módulo es seguro para subprocesos, que puede comenzar mediante la búsqueda de usos de primitivas de sincronización hilo de los threading o multiprocessing módulos, o el uso de queue.Queue.

ACTUALIZACIÓN

Aquí es un fragmento de código fuente relevante de urllib2.py (Python 2.7.2):

_opener = None 
def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): 
    global _opener 
    if _opener is None: 
     _opener = build_opener() 
    return _opener.open(url, data, timeout) 

def install_opener(opener): 
    global _opener 
    _opener = opener 

Hay una condición de carrera obvia cuando hilos concurrentes llaman install_opener() y urlopen().

Además, tenga en cuenta que llamar urlopen() con un objeto como parámetro Requesturl puede mutar el objeto Request (vea la fuente de OpenerDirector.open()), por lo que no es seguro llamar simultáneamente urlopen() con un Request objeto compartido.

En total, urlopen() es seguro para subprocesos si se cumplen las siguientes condiciones:

  • install_opener() no se llama desde otro hilo.
  • A no compartidoRequest objeto, o una cadena se utiliza como el parámetro url.
+0

@Gregg - ¿Podría decir algo acerca de cómo determinaría la seguridad de los hilos inspeccionando el código de un módulo en particular? A menudo tengo esta pregunta exacta ... –

+2

@ire_and_curses: He expandido mi respuesta en consecuencia. – Gregg

+0

Gracias - +1 de mi parte. –

Cuestiones relacionadas