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