Multihilo en Python | Serie 1

Este artículo cubre los conceptos básicos de subprocesos múltiples en el lenguaje de programación Python. Al igual que el multiprocesamiento , el multiproceso es una forma de lograr la multitarea. En subprocesos múltiples, se utiliza el concepto de subprocesos . Primero comprendamos el concepto de hilo en la arquitectura de la computadora.

Hilo

En informática, un proceso es una instancia de un programa de computadora que se está ejecutando. Cualquier proceso tiene 3 componentes básicos:

  • Un programa ejecutable.
  • Los datos asociados que necesita el programa (variables, espacio de trabajo, búferes, etc.)
  • El contexto de ejecución del programa (Estado del proceso)

Un subproceso es una entidad dentro de un proceso que se puede programar para su ejecución. Además, es la unidad de procesamiento más pequeña que se puede realizar en un SO (Sistema Operativo). En palabras simples, un hilo es una secuencia de tales instrucciones dentro de un programa que se puede ejecutar independientemente de otro código. Para simplificar, puede suponer que un subproceso es simplemente un subconjunto de un proceso. Un subproceso contiene toda esta información en un Bloque de control de subprocesos (TCB) :

  • Identificador de subproceso: se asigna una identificación única (TID) a cada nuevo subproceso
  • Puntero de pila: apunta a la pila del subproceso en el proceso. Stack contiene las variables locales bajo el alcance del subproceso.
  • Contador de programa: un registro que almacena la dirección de la instrucción que está siendo ejecutada actualmente por el hilo.
  • Estado del subproceso: puede estar en ejecución, listo, esperando, iniciado o terminado.
  • Conjunto de registros del subproceso: registros asignados al subproceso para los cálculos.
  • Puntero de proceso principal: un puntero al bloque de control de proceso (PCB) del proceso en el que vive el subproceso.

Considere el siguiente diagrama para comprender la relación entre el proceso y su subproceso:

subprocesos múltiples:

Pueden existir múltiples subprocesos dentro de un proceso donde:

  • Cada subproceso contiene su propio conjunto de registros y variables locales (almacenadas en la pila) .
  • Todos los subprocesos de un proceso comparten variables globales (almacenadas en montón) y el código del programa .

Considere el siguiente diagrama para comprender cómo existen varios subprocesos en la memoria: El subproceso múltiple se define como la capacidad de un procesador para ejecutar varios subprocesos al mismo tiempo.

En una CPU simple de un solo núcleo, se logra mediante cambios frecuentes entre subprocesos. Esto se denomina cambio de contexto . En el cambio de contexto, el estado de un subproceso se guarda y el estado de otro subproceso se carga cada vez que se produce una interrupción (debido a E/S o establecida manualmente). El cambio de contexto tiene lugar con tanta frecuencia que todos los subprocesos parecen estar ejecutándose en paralelo (esto se denomina multitarea ).

Considere el siguiente diagrama en el que un proceso contiene dos subprocesos activos: 

Multihilo en Python

En Python, el módulo de subprocesos proporciona una API muy simple e intuitiva para generar múltiples subprocesos en un programa. Consideremos un ejemplo simple usando un módulo de subprocesamiento: 

Python3

# Python program to illustrate the concept
# of threading
# importing the threading module
import threading
 
 
def print_cube(num):
    "
    "
    "
    function to print cube of given num
    "
    "
    "
    print(& quot
           Cube: {} & quot
           .format(num * num * num))
 
 
def print_square(num):
    "
    "
    "
    function to print square of given num
    "
    "
    "
    print(& quot
           Square: {} & quot
           .format(num * num))
 
 
if __name__ == "
__main__ & quot
:
    # creating thread
    t1 = threading.Thread(target=print_square, args=(10,))
    t2 = threading.Thread(target=print_cube, args=(10,))
 
    # starting thread 1
    t1.start()
    # starting thread 2
    t2.start()
 
    # wait until thread 1 is completely executed
    t1.join()
    # wait until thread 2 is completely executed
    t2.join()
 
    # both threads completely executed
    print(& quot
           Done!& quot
           )
Square: 100
Cube: 1000
Done!

Tratemos de entender el código anterior:

  • Para importar el módulo de subprocesos, hacemos:
import threading
  • Para crear un nuevo hilo, creamos un objeto de la clase Thread . Toma los siguientes argumentos:
    • target : la función que ejecutará el subproceso
    • args : los argumentos que se pasarán a la función de destino
  • Para iniciar un hilo, usamos el método de inicio de la clase Thread .
t1.start()
t2.start()
  • Una vez que se inician los subprocesos, el programa actual (puede considerarlo como un subproceso principal) también sigue ejecutándose. Para detener la ejecución del programa actual hasta que se complete un hilo, usamos el método de unión .
t1.join()
t2.join()
  • Como resultado, el programa actual primero esperará a que se complete t1 y luego t2 . Una vez finalizadas, se ejecutan las sentencias restantes del programa actual.

Considere el siguiente diagrama para una mejor comprensión de cómo funciona el programa anterior: 

Considere el programa de Python que se proporciona a continuación en el que imprimimos el nombre del hilo y el proceso correspondiente para cada tarea: 

Python3

# Python program to illustrate the concept
# of threading
import threading
import os
 
def task1():
    print("Task 1 assigned to thread: {}".format(threading.current_thread().name))
    print("ID of process running task 1: {}".format(os.getpid()))
 
def task2():
    print("Task 2 assigned to thread: {}".format(threading.current_thread().name))
    print("ID of process running task 2: {}".format(os.getpid()))
 
if __name__ == "__main__":
 
    # print ID of current process
    print("ID of process running main program: {}".format(os.getpid()))
 
    # print name of main thread
    print("Main thread name: {}".format(threading.current_thread().name))
 
    # creating threads
    t1 = threading.Thread(target=task1, name='t1')
    t2 = threading.Thread(target=task2, name='t2') 
 
    # starting threads
    t1.start()
    t2.start()
 
    # wait until all threads finish
    t1.join()
    t2.join()
ID of process running main program: 11758
Main thread name: MainThread
Task 1 assigned to thread: t1
ID of process running task 1: 11758
Task 2 assigned to thread: t2
ID of process running task 2: 11758

Tratemos de entender el código anterior:

  • Usamos la función os.getpid() para obtener la ID del proceso actual.
print("ID of process running main program: {}".format(os.getpid()))
  • Como queda claro a partir de la salida, el ID del proceso sigue siendo el mismo para todos los subprocesos.
  • Usamos la función threading.main_thread() para obtener el objeto del hilo principal. En condiciones normales, el subproceso principal es el subproceso desde el que se inició el intérprete de Python. El atributo de nombre del objeto hilo se usa para obtener el nombre del hilo.
print("Main thread name: {}".format(threading.main_thread().name))
  • Usamos la función threading.current_thread() para obtener el objeto del hilo actual.
print("Task 1 assigned to thread: {}".format(threading.current_thread().name))

El siguiente diagrama aclara el concepto anterior:

Entonces, esta fue una breve introducción a los subprocesos múltiples en Python. El siguiente artículo de esta serie trata sobre la sincronización entre varios subprocesos . Multihilo en Python | Juego 2 (Sincronización) 

Este artículo es una contribución de Nikhil Kumar . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *