2010-03-20 25 views
8

En mi secuencia de comandos, tengo una función foo que básicamente utiliza pynotify para notificar al usuario sobre algo repetidamente después de un intervalo de tiempo de 15 minutos.¿Debo usar horquilla o hilos?

def foo: 
    while True: 
     """Does something""" 
     time.sleep(900) 

Mi script principal tiene que interactuar con el usuario & hace todo lo demás, así que simplemente no puede llamar a la función foo(). directamente.

¿Cuál es la mejor manera de hacerlo y por qué? ¿Usando un tenedor o hilos?

+0

Hmm dos respuestas contradictorias ... – kennytm

+0

@Kenny TM: No es de extrañar. "Mejor" no está definido en la pregunta. Además, es altamente discutible para la mayoría de las definiciones de "Mejor". –

Respuesta

9

que no le dirá cuál usar, pero aquí están algunas de las ventajas de cada uno:

Hilos puede iniciar más rápidamente que los procesos y subprocesos utilizan menos recursos del sistema operativo de los procesos, incluyendo memoria, manejadores de archivos, etc. Los subprocesos también le dan la opción de comunicarse a través de variables compartidas (aunque muchos dirían que esto es más una desventaja que una ventaja - Ver más abajo).

Cada uno de los procesos tiene su propia memoria y variables, lo que significa que los procesos generalmente se comunican al enviarse mensajes entre ellos. Esto es mucho más fácil de hacer correctamente que tener los hilos comunicados a través de la memoria compartida. Los procesos también se pueden ejecutar de manera simultánea, de modo que si tiene múltiples núcleos de CPU, puede mantenerlos ocupados mediante procesos. En Python *, el global interpreter lock evita que los hilos hagan mucho uso de más de un núcleo.


* - Es decir, CPython, que la implementación de Python que se obtiene si se va a http://python.org y descargar Python. Otras implementaciones de Python (como Jython) no necesariamente prohíben que Python ejecute subprocesos en múltiples CPU simultáneamente. Gracias a @EOL por la aclaración.

+0

que utilizan hilos bcos la tarea no era la CPU y también me hizo uso de la horquilla como también más lenta para realmente crear toda una nueva PCB .. –

+3

Probablemente decir "En CPython, el cierre global del intérprete ...". De hecho, no hay GIL en algunas otras implementaciones de Python (Jython, Iron Python, ...). – EOL

+0

@EOL - Cierto. Supuse que la persona que preguntaba estaba usando CPython, ya que las personas generalmente especifican si están usando cualquier cosa * que no sea * CPython. Sin embargo, tengo un punto: actualizaré mi respuesta. –

3

Los procesos son mucho más simples. Solo déjelos sueltos y deje que el SO lo maneje.

Además, los procesos son a menudo mucho más eficientes. Los procesos no comparten un grupo común de recursos de E/S; son completamente independientes.

Python's subprocess.Popen se encarga de todo.

+0

+1 de mí - S. Lott es mucho más autorizada que yo, especialmente cuando se trata de Python. – duffymo

1

Si te refieres a os.fork con fork te evitaré usar eso. No es multiplataforma y tiene un nivel demasiado bajo; deberá implementar la comunicación entre los procesos usted mismo.

Si desea utilizar un proceso separado, utilice el módulo de subproceso o si está en Python 2.6 o posterior, el nuevo módulo multiprocessing. Esto tiene una API muy similar al módulo de subprocesamiento, por lo que podría comenzar a usar subprocesos y luego cambiar fácilmente a procesos, o viceversa.

Para lo que quiere hacer, creo que usaría hilos, a menos que """does something""" requiera mucha CPU y quiera aprovechar varios núcleos, lo que dudo en este caso particular.

+0

Si tengo una CPU intensiva, ¿cuáles debo elegir y por qué? –

4

Para este tipo de problemas, ni hilos ni los procesos bifurcados parece el enfoque correcto. Si todo lo que quiere hacer es notificar al usuario de algo cada 15 minutos, ¿por qué no utilizar un ciclo de eventos como el reactor de GLib o Twisted? Esto le permite programar operaciones que deben ejecutarse de vez en cuando, y continuar con el resto de su programa.

+0

Soy un principiante, así que no tengo idea de cómo lo implemento. Pero tu respuesta parece convincente ... –

4

El uso de procesos múltiples le permite explotar múltiples núcleos de CPU al mismo tiempo, mientras que en CPython, usar hilos no (los hilos se turnan usando un solo núcleo de CPU), así que si tiene un trabajo intensivo de CPU y absolutamente desea utilizar hilos, debe considerar Jython o IronPython; con CPython, esta consideración es a menudo suficiente para influir en la elección hacia el módulo de multiprocessing y lejos de la threading uno (ofrecen las interfaces muy similares, porque multiprocessing fue diseñado para ser fácilmente puesto en marcha en lugar de threading).

Neto de esta consideración crucial, los subprocesos a menudo pueden ser una mejor opción (rendimiento) en Windows (donde hacer un nuevo proceso es una tarea pesada), pero con menos frecuencia en variantes de Unix (Linux, versiones BSD, OpenSolaris, MacOSX, ...), ya que hacer un nuevo proceso es más rápido allí (pero si está utilizando IronPython o Jython, debe comprobar, en las plataformas que le interesan, que esto todavía se aplica en las máquinas virtuales en cuestión - CLR con .NET o Mono para IronPython, su JVM de elección para Jython).