thread semaforos programa multitarea library hilos entre eliminar ejemplos detener comunicacion python multithreading

semaforos - python thread library



¿Cómo funcionan los hilos en Python, y cuáles son los peligros específicos de Python? (7)

Intente recordar que el GIL está configurado para sondear de vez en cuando para mostrar la apariencia de varias tareas. Esta configuración puede ser ajustada, pero ofrezco la sugerencia de que debería haber trabajo que los hilos están haciendo o muchos interruptores de contexto van a causar problemas.

Me atrevería a sugerir múltiples padres en los procesadores y tratar de mantener trabajos similares en el mismo núcleo (s).

He estado tratando de entender cómo funcionan los hilos en Python, y es difícil encontrar buena información sobre cómo funcionan. Puede que me esté perdiendo un enlace o algo así, pero parece que la documentación oficial no es muy completa sobre el tema, y ​​no he podido encontrar un buen artículo.

Por lo que puedo decir, solo se puede ejecutar un hilo a la vez, y el hilo activo cambia cada 10 instrucciones más o menos?

¿Dónde hay una buena explicación, o puede proporcionar una? También sería muy agradable estar al tanto de los problemas comunes con los que se tropieza al usar hilos con Python.


Python es un lenguaje bastante fácil de usar, pero hay advertencias. Lo más importante que debe saber es el bloqueo de intérprete global. Esto permite que solo un hilo acceda al intérprete. Esto significa dos cosas: 1) rara vez se encuentra utilizando una declaración de bloqueo en python y 2) si desea aprovechar los sistemas multiprocesador, debe usar procesos separados. EDITAR: También debo señalar que puede poner algo del código en C / C ++ si también quiere sortear el GIL.

Por lo tanto, debe volver a considerar por qué desea utilizar los hilos. Si desea paralelizar su aplicación para aprovechar la arquitectura de doble núcleo, debe considerar dividir su aplicación en múltiples procesos.

Si desea mejorar la capacidad de respuesta, debe CONSIDERAR el uso de hilos. Sin embargo, existen otras alternativas, a saber, la microthreading . También hay algunos marcos que debe considerar:


Sí, debido al bloqueo de intérprete global (GIL) solo puede ejecutar un hilo a la vez. Aquí hay algunos enlaces con algunas ideas sobre esto:

Desde el último enlace, una cita interesante:

Déjame explicarte todo lo que eso significa. Los hilos se ejecutan dentro de la misma máquina virtual y, por lo tanto, se ejecutan en la misma máquina física. Los procesos pueden ejecutarse en la misma máquina física o en otra máquina física. Si diseñas tu aplicación alrededor de subprocesos, no has hecho nada para acceder a varias máquinas. Por lo tanto, puede escalar para que haya tantos núcleos en una sola máquina (lo que ocurrirá con el tiempo), pero para llegar realmente a las escalas de red, tendrá que resolver el problema de las máquinas múltiples de todos modos.

Si desea utilizar multinúcleo, pyprocessing define una API basada en proceso para realizar una paralelización real. El PEP también incluye algunos puntos de referencia interesantes.


Una solución fácil para GIL es el módulo de multiprocessing . Se puede utilizar como un reemplazo en el módulo de subprocesamiento pero utiliza múltiples procesos de Intérprete en lugar de subprocesos. Debido a esto, hay un poco más de sobrecarga que un simple enhebrado para cosas simples, pero le da la ventaja de una paralelización real si la necesita. También escala fácilmente a múltiples máquinas físicas.

Si necesita una paralelización a gran escala mayor que la que yo buscaría más adelante, pero si solo quiere escalar a todos los núcleos de una computadora o unas pocas diferentes sin todo el trabajo que implicaría implementar un marco más completo, entonces esto es para usted .


Use subprocesos en Python si los trabajadores individuales están realizando operaciones vinculadas de E / S. Si intenta escalar a través de múltiples núcleos en una máquina, encuentre un buen marco pyprocessing para python o elija un idioma diferente.


Nota: cada vez que menciono el thread me refiero específicamente a los hilos en python hasta que se indique explícitamente.

Los hilos funcionan un poco diferente en python si vienes del fondo C/C++ . En python, solo un hilo puede estar en estado de ejecución en un momento determinado. Esto significa que los hilos en python no pueden aprovechar realmente la potencia de múltiples núcleos de procesamiento ya que, por diseño, no es posible que los hilos se ejecuten paralelamente en múltiples núcleos.

Como la gestión de memoria en python no es segura para subprocesos, cada subproceso requiere un acceso exclusivo a las estructuras de datos en el intérprete de Python. Este acceso exclusivo se adquiere mediante un mecanismo llamado GIL (bloqueo de interpretación global) .

Why does python use GIL?

Para evitar que varios subprocesos accedan al estado del intérprete simultáneamente y corrompan el estado del intérprete.

La idea es cada vez que se ejecuta un hilo (incluso si es el hilo principal) , se adquiere un GIL y después de un intervalo de tiempo predefinido, el GIL es liberado por el hilo actual y readquirido por otro hilo (si lo hay).

Why not simply remove GIL?

No es que sea imposible eliminar GIL, es solo que, al hacerlo, terminamos colocando bloqueos mutiples dentro del intérprete para serializar el acceso, lo que hace que incluso una sola aplicación con subprocesos sea menos eficaz.

por lo tanto, el costo de eliminar GIL se compensa con la reducción del rendimiento de una aplicación con un único subproceso, que nunca se desea.

So when does thread switching occurs in python?

El cambio de hilo ocurre cuando se lanza GIL. Entonces, ¿cuándo se libera GIL? Hay dos escenarios para tener en cuenta.

Si un hilo está haciendo operaciones de límite de CPU (procesamiento de imagen Ex).

En versiones anteriores de python, la conmutación de subprocesos solía ocurrir después de un número fijo de instrucciones de python. Estaba predeterminada de forma predeterminada en 100 Resultó que no es una política muy buena para decidir cuándo debería producirse el cambio ya que el tiempo empleado en ejecutar un solo la instrucción puede variar de milisegundos a incluso segundos. Por lo tanto, liberar GIL después de cada 100 instrucciones, independientemente del tiempo que tarden en ejecutarse, es una política deficiente.

En las nuevas versiones, en lugar de utilizar el recuento de instrucciones como una métrica para cambiar el hilo, se utiliza un intervalo de tiempo configurable. El intervalo de cambio predeterminado es de 5 milisegundos. Puede obtener el intervalo de cambio actual utilizando sys.getswitchinterval() . Esto puede ser alterado usando sys.setswitchinterval()

Si un subproceso está haciendo algunas operaciones IO Bound (acceso al sistema de archivos Ex o
red IO)

GIL se libera cuando el subproceso está esperando a que se complete alguna operación de E / S.

Which thread to switch to next?

El intérprete no tiene su propio planificador. El hilo que se programa al final del intervalo es la decisión del sistema operativo. .


A continuación se muestra una muestra básica de enhebrado. Engendrará 20 hilos; cada hilo dará salida a su número de hilo. Ejecútelo y observe el orden en que se imprimen.

import threading class Foo (threading.Thread): def __init__(self,x): self.__x = x threading.Thread.__init__(self) def run (self): print str(self.__x) for x in xrange(20): Foo(x).start()

Como ha insinuado, los hilos de Python se implementan a través del corte de tiempo. Así es como obtienen el efecto "paralelo".

En mi ejemplo, mi clase Foo amplía el hilo, luego implemento el método de run , que es donde va el código que le gustaría ejecutar en un hilo. Para iniciar el hilo, llame a start() en el objeto de hilo, que invocará automáticamente el método de run ...

Por supuesto, esto es solo lo básico. Eventualmente querrás aprender sobre semáforos, mutexes y bloqueos para la sincronización de hilos y el envío de mensajes.