TECH4GEEKS-LOGO-HEADER
Oxary Magazine
$10 – $15 / Week

Enhebrado de Python: una introducción – Geekflare

En este tutorial, aprenderá a usar las funciones integradas de Python enhebrar módulo para explorar las capacidades de subprocesos múltiples en Python.

Comenzando con los conceptos básicos de procesos y subprocesos, aprenderá cómo funcionan los subprocesos múltiples en Python, mientras comprende los conceptos de concurrencia y paralelismo. Luego aprenderá cómo iniciar y ejecutar uno o más subprocesos en Python utilizando el módulo de subprocesos incorporado.

Empecemos.

Procesos vs hilos: ¿cuáles son las diferencias?

¿Qué es un proceso?

A tratar es cualquier instancia de un programa que necesita ejecutarse.

Puede ser cualquier cosa: una secuencia de comandos de Python o un navegador web como Chrome para una aplicación de videoconferencia. Si ejecuta el Administrador de tareas en su máquina y navegue hasta Rendimiento –> UPCpodrá ver los procesos y subprocesos que se ejecutan en los núcleos de su CPU.

CPU-proc-hilos

Comprensión de procesos y subprocesos

Internamente, un proceso tiene una memoria dedicada que almacena el código y los datos correspondientes al proceso.

Un proceso consta de uno o más hijo. Un hilo es la secuencia más pequeña de instrucciones que el sistema operativo puede ejecutar y representa el flujo de ejecución.

Cada subproceso tiene su propia pila y sus propios registros, pero no tiene memoria dedicada. Todos los subprocesos asociados con un proceso pueden acceder a los datos. Por lo tanto, los datos y la memoria son compartidos por todos los subprocesos de un proceso.

procesos-e-hilos

En un procesador N-core, N procesos pueden ejecutarse en paralelo al mismo tiempo. Sin embargo, dos subprocesos del mismo proceso nunca pueden ejecutarse en paralelo, pero pueden ejecutarse simultáneamente. Discutiremos el concepto de concurrencia versus paralelismo en la siguiente sección.

Basándonos en lo que hemos aprendido hasta ahora, resumamos las diferencias entre un proceso y un hilo.

CaracterísticaTratarHiloMemoriaMemoria dedicadaMemoria compartidaModo de ejecuciónParalelo, ConcurrenteConcurrente; pero no paraleloEjecución dirigida por Sistema operativoCPython Intérprete

Multihilo en Python

En Python, el Bloqueo de intérprete global (GIL) se asegura de que sólo uno thread puede adquirir el bloqueo y ejecutarse en cualquier momento. Todos los subprocesos deben adquirir este bloqueo para ejecutarse. Esto asegura que solo se puede ejecutar un subproceso, en un momento dado, y evita simultáneo subprocesos múltiples.

  10 ejemplos de Bash For loop con explicaciones

Por ejemplo, considere dos subprocesos, t1 y t2, del mismo proceso. Dado que los subprocesos comparten los mismos datos cuando t1 lee un valor k particular, t2 puede modificar el mismo valor k. Esto puede conducir a bloqueos y resultados no deseados. Pero solo uno de los subprocesos puede adquirir el bloqueo y ejecutarse en cualquier instancia. Así, GIL también asegura seguridad de alambre.

Entonces, ¿cómo logramos capacidades de subprocesos múltiples en Python? Para entender esto, analicemos los conceptos de concurrencia y paralelismo.

Concurrencia versus paralelismo: una descripción general

Considere un procesador con más de un núcleo. En la siguiente ilustración, la CPU tiene cuatro núcleos. Esto significa que podemos tener cuatro operaciones diferentes ejecutándose en paralelo en un momento dado.

Si hay cuatro procesos, cada uno de los procesos puede ejecutarse de forma independiente y simultánea en cada uno de los cuatro núcleos. Supongamos que cada proceso tiene dos subprocesos.

paralelismo multinúcleo

Para comprender cómo funciona el subprocesamiento, pasemos de una arquitectura de procesador de varios núcleos a una arquitectura de un solo núcleo. Como se mencionó, solo un subproceso puede estar activo en una instancia de ejecución en particular; pero el núcleo de la CPU puede cambiar entre subprocesos.

codificado

Por ejemplo, los subprocesos vinculados a E/S a menudo esperan operaciones de E/S: lectura de entrada del usuario, lecturas de bases de datos y operaciones de archivos. Durante este tiempo de espera, puede liberar el bloqueo para que el otro subproceso pueda ejecutarse. El tiempo de espera también puede ser una operación simple como dormir durante n segundos.

En resumen: durante las operaciones de espera, el subproceso libera el bloqueo, lo que permite que el núcleo de la CPU cambie a otro subproceso. El subproceso anterior reanuda la ejecución después de que finaliza el período de espera. Este proceso, en el que el núcleo de la CPU cambia simultáneamente entre subprocesos, facilita la multiproceso. ✅

Si desea implementar el paralelismo a nivel de proceso en su aplicación, considere usar multiprocesamiento Al lugar.

Módulo de subprocesamiento de Python: primeros pasos

Python viene con un módulo de subprocesamiento que puede importar al script de Python.

import threading

Para crear un objeto de hilo en Python, puede usar el constructor de hilos: threading.Thread(…). Esta es la sintaxis genérica que es suficiente para la mayoría de las implementaciones de subprocesos:

threading.Thread(target=...,args=...)

Aquí,

  • target es el argumento de palabra clave que indica un Python invocable
  • args es la tupla de argumentos que toma el objetivo.

Necesitará Python 3.x para ejecutar el código de muestra de este tutorial. Descargar código y síguelo.

  Cómo realizar la división del suelo en Python

Cómo definir y ejecutar subprocesos en Python

Definamos un hilo que ejecuta una función de destino.

La función de destino es some_func.

import threading
import time

def some_func():
    print("Running some_func...")
    time.sleep(2)
    print("Finished running some_func.")

thread1 = threading.Thread(target=some_func)
thread1.start()
print(threading.active_count())

Analicemos lo que hace el fragmento de código anterior:

  • Importa subprocesos y módulos de tiempo.
  • La función some_func tiene instrucciones print() descriptivas e incluye una operación de suspensión de dos segundos: time.sleep(n) hace que la función entre en suspensión durante n segundos.
  • A continuación, definimos un subproceso thread_1 con el objetivo como some_func. threading.Thread(target=…) crea un objeto de hilo.
  • Notar: Especifique el nombre de la función, no una llamada de función; usar some_func y no alguna_función().
  • La creación de un objeto de hilo no inicia un hilo; llamar al método start () en el objeto de hilo hace esto.
  • Para obtener el número de subprocesos activos, usamos la función active_count().

La secuencia de comandos de Python se ejecuta en el subproceso principal y creamos otro subproceso (subproceso1) para ejecutar la función some_func de modo que la cantidad de subprocesos activos sea dos, como se muestra en el resultado:

# Output
Running some_func...
2
Finished running some_func.

Si observamos más de cerca la salida, vemos que cuando se inicia thread1, se ejecuta la primera declaración de impresión. Pero durante la operación de suspensión, la CPU cambia al subproceso principal e imprime el número de subprocesos activos, sin esperar a que subproceso1 termine de ejecutarse.

hilo1-ex

Espere a que los subprocesos completen la ejecución

Si desea que el subproceso1 complete la ejecución, puede llamar al método join() después de iniciar el subproceso. Esto esperará a que subproceso1 complete su ejecución sin cambiar al subproceso principal.

import threading
import time

def some_func():
    print("Running some_func...")
    time.sleep(2)
    print("Finished running some_func.")

thread1 = threading.Thread(target=some_func)
thread1.start()
thread1.join()
print(threading.active_count())

Ahora hilo1 ha terminado de ejecutarse antes de que imprimamos el número de hilos activos. Entonces, solo se está ejecutando el subproceso principal, lo que significa que la cantidad de subprocesos activos es uno. ✅

# Output
Running some_func...
Finished running some_func.
1

Cómo ejecutar varios subprocesos en Python

A continuación, creemos dos subprocesos para realizar dos funciones diferentes.

Aquí count_down es una función que toma un número como argumento y cuenta hacia atrás desde ese número hasta cero.

def count_down(n):
    for i in range(n,-1,-1):
        print(i)

Definimos count_up, otra función de Python que cuenta desde cero hasta un número dado.

def count_up(n):
    for i in range(n+1):
        print(i)

📑 Al usar la función range() con la sintaxis range(start, stop, step), la parada del punto final se excluye de forma predeterminada.

  5 formas de dar estilo a React usando CSS [2023]

– Para contar hacia atrás desde un número específico hasta cero, puede usar un valor de paso negativo de -1 y establecer el valor de parada en -1 para que se incluya el cero.

– De manera similar, para contar hasta n, debe establecer el valor de parada en n + 1. Dado que los valores predeterminados de inicio y paso son 0 y 1 respectivamente, puede usar el rango (n + 1) para obtener la secuencia 0 a través de n.

A continuación, definimos dos subprocesos, subproceso1 y subproceso2 para realizar las funciones count_down y count_up, respectivamente. Agregamos instrucciones de impresión y operaciones de suspensión para ambas funciones.

Al crear objetos de hilo, tenga en cuenta que los argumentos de la función de destino deben especificarse como una tupla, en el parámetro args. Como ambas funciones (count_down y count_up) toman un solo argumento. Deberá insertar una coma explícitamente después del valor. Esto garantiza que el argumento siempre se pase como una tupla, porque se infiere que los elementos subsiguientes son Ninguno.

import threading
import time

def count_down(n):
    for i in range(n,-1,-1):
        print("Running thread1....")
        print(i)
        time.sleep(1)


def count_up(n):
    for i in range(n+1):
        print("Running thread2...")
        print(i)
        time.sleep(1)

thread1 = threading.Thread(target=count_down,args=(10,))
thread2 = threading.Thread(target=count_up,args=(5,))
thread1.start()
thread2.start()

En la salida:

  • La función count_up se ejecuta en thread2 y cuenta hasta 5 desde 0.
  • La función count_down se ejecuta en thread1 contando de 10 a 0.
# Output
Running thread1....
10
Running thread2...
0
Running thread1....
9
Running thread2...
1
Running thread1....
8
Running thread2...
2
Running thread1....
7
Running thread2...
3
Running thread1....
6
Running thread2...
4
Running thread1....
5
Running thread2...
5
Running thread1....
4
Running thread1....
3
Running thread1....
2
Running thread1....
1
Running thread1....
0

Puede ver que thread1 y thread2 se ejecutan alternativamente, porque ambos implican una operación de espera (suspensión). Una vez que la función count_up ha terminado de contar hasta 5, thread2 ya no está activo. Entonces obtenemos la salida correspondiente solo a thread1.

Resumen

En este tutorial, aprendió a usar el módulo de subprocesos integrado de Python para implementar subprocesos múltiples. He aquí un resumen de las principales conclusiones:

  • los Hilo El constructor se puede usar para crear un objeto de hilo. Usando enhebrar.Subproceso(objetivo=,argumentos=()) crear un hilo que ejecute el objetivo invocable con los argumentos especificados en argumentos.
  • El programa Python se ejecuta en un subproceso principal, por lo que los objetos de subproceso que crea son subprocesos adicionales. Puedes llamar cuenta_activa() La función devuelve el número de subprocesos activos en cualquier instancia.
  • Puedes iniciar un hilo usando inicio() en el objeto del hilo y espere a que complete su ejecución usando el reunirse con() método.

Puede codificar ejemplos adicionales cambiando los tiempos de espera, probando una operación de E/S diferente, etc. Asegúrese de implementar subprocesos múltiples en sus futuros proyectos de Python. ¡Feliz codificación!🎉

Fuente

Etiquetas

Comparte en:

Ultimos Post

Categorias

Lorem ipsum dolor sit amet, consectetur adipiscing elit eiusmod tempor ncididunt ut labore et dolore magna
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore