Prioridad de subprocesos de Python

Abid Ullah 21 junio 2023
  1. Enhebrar en Python
  2. Control de la prioridad de programación de los subprocesos de Python
Prioridad de subprocesos de Python

Este artículo tiene como objetivo explicar cómo podemos usar la programación de subprocesos en Python para que sea una prioridad. Aquí, hablaremos sobre la programación de un hilo de prioridad en Python y su uso con un buen programa de ejemplo.

Con Python threading, podemos ejecutar diferentes partes de nuestro programa simultáneamente, lo que facilita el diseño de su programa. Le mostraremos cómo usar subprocesos para acelerar su programa de Python si sabe algo de Python.

Enhebrar en Python

Threading es la capacidad de ejecutar múltiples instrucciones simultáneamente. Como exploramos en este artículo, podemos priorizar los hilos ajustando la programación.

Se utiliza un bloqueo de intérprete global (GIL) para implementar subprocesos de Python, lo que significa que la prioridad de un subproceso no se puede controlar. Controlar hilos usando una prioridad requiere que creemos un sistema de prioridad implícito.

Al enhebrar, puede imaginar dos (o más) procesadores ejecutándose en su programa simultáneamente, cada uno realizando una tarea independiente.

Eso está muy cerca de ser verdad. Cada subproceso se ejecutará en un procesador simultáneamente, incluso en diferentes procesadores.

Para ejecutar varias tareas simultáneamente, necesitará una implementación de Python no estándar, es posible que su código deba escribirse en un idioma diferente o que deba usar multiprocesamiento con sobrecarga adicional.

La implementación de C de Python no siempre admite la creación de subprocesos, por lo que es posible que la creación de subprocesos no acelere todas las tareas. Las interacciones GIL limitan la cantidad de subprocesos de Python que pueden ejecutarse simultáneamente.

En general, la creación de subprocesos es una opción adecuada para tareas que pasan mucho tiempo esperando eventos externos. Es posible que los problemas que requieran una gran cantidad de cómputos de la CPU pero pasen poco tiempo esperando eventos externos no se ejecuten tan rápido como otros.

Control de la prioridad de programación de los subprocesos de Python

Asegurarnos de que estamos trabajando con la versión correcta de Python es crucial. Estamos usando la versión 3.10.4 específicamente para este artículo.

Es posible verificar la versión de python actualmente instalada ejecutando el siguiente comando en la terminal.

python --version

Importación de bibliotecas útiles

El siguiente paso es aprender a crear un hilo usando la prioridad de programación después de comprender qué es un hilo. La biblioteca estándar de Python proporciona la mayoría de las primitivas que verá en este artículo a través de subprocesos.

En este módulo, Thread proporciona una interfaz agradable para interactuar con hilos, encapsulándolos muy bien.

Ahora pasamos a la siguiente fase del programa, donde importamos las bibliotecas necesarias para programar las prioridades de los hilos de Python.

Código de ejemplo:

import time
from threading import Thread
from time import sleep

Es posible iniciar un hilo separado usando la instancia Thread y diciéndole .start().

Código de ejemplo:

import logging
import threading
import time


def the_thread_function(name):
    logging.info("The thread %s: Beginning now", name)
    time.sleep(2)
    logging.info("The Thread %s: Ends", name)


if __name__ == "__main__":
    format = "%(asctime)s: %(message)s"
    logging.basicConfig(format=format, level=logging.INFO, datefmt="%H:%M:%S")
    logging.info("Main    : Now before creating a thread")
    x = threading.Thread(target=the_thread_function, args=(1,))
    logging.info("Main    : Earlier than running threading")
    x.start()
    logging.info("Main    : Now wait for the thread to End")
    # x.join()
    logging.info("Main    : All Finish")

Producción :

17:06:51: Main    : Now before creating a thread
17:06:51: Main    : Earlier than running threading
17:06:51: The thread 1: Beginning now
17:06:51: Main    : Now wait for the thread to End
17:06:51: Main    : All Finish
17:06:53: The Thread 1: Ends

En las declaraciones de registro, puede ver que la sección principal es crear e iniciar el hilo: crea un hilo pasándole una lista de argumentos y la función que desea llamar.

En este caso, se le dice al Thread que ejecute thread_function() y le pase 1 como argumento.

Trabajar con muchos subprocesos Programar prioridad en Python

Actualmente, el código de ejemplo funciona solo con dos subprocesos, el subproceso principal y el subproceso que comenzó con el objeto de subproceso Subproceso. A menudo querrá iniciar muchos hilos y hacer que trabajen en cosas interesantes.

A continuación, veamos un método más fácil para hacerlo. Comencemos mirando la forma más difícil.

Código de ejemplo:

import logging
import threading
import time


def thread_function(name):
    logging.info("Thread %s: Beginning", name)
    time.sleep(2)
    logging.info("Thread %s: Ending", name)


if __name__ == "__main__":
    format = "%(asctime)s: %(message)s"
    logging.basicConfig(format=format, level=logging.INFO, datefmt="%H:%M:%S")
    threads = list()
    for index in range(3):
        logging.info("Main    : create and start thread %d.", index)
        x = threading.Thread(target=thread_function, args=(index,))
        threads.append(x)
        x.start()
    for index, thread in enumerate(threads):
        logging.info("Main    : Before joining thread %d.", index)
        thread.join()
        logging.info("Main    : thread %d end", index)

Producción :

17:09:01: Main    : create and start thread 2.
17:09:01: Thread 2: Beginning
17:09:01: Main    : Before joining thread 0.
17:09:03: Thread 0: Ending
17:09:03: Main    : thread 0 end
17:09:03: Main    : Before joining thread 1.
17:09:03: Thread 1: Ending
17:09:03: Main    : thread 1 end
17:09:03: Main    : Before joining thread 2.
17:09:03: Thread 2: Ending
17:09:03: Main    : thread 2 end

Comenzamos un hilo de la misma manera que comenzamos un hilo antes, creando un objeto Hilo y luego llamando a .start(). Mantener una lista de objetos Thread permite que el programa los espere más tarde usando .join().

Cuando observe la salida detenidamente, notará que los tres subprocesos comienzan en el orden esperado. ¡En este caso, sin embargo, terminan en el orden inverso!

Múltiples ejecuciones producirán y darán salida a los diferentes pedidos. Busque el mensaje Thread x: Nearing End para indicarle cuándo llegará al final cada Thread.

Los sistemas operativos determinan el orden en que se ejecutan los subprocesos, lo cual es bastante difícil de predecir. El uso de subprocesos en los algoritmos puede variar (y probablemente lo hará) de una ejecución a otra, así que tenga esto en cuenta al desarrollar algoritmos.

Es una gran cosa que Python proporcione varias primitivas para coordinar hilos y coordinarlos entre sí. Primero veremos cómo facilitar la administración de un grupo de subprocesos.

Creando Clase Trabajador

Esta clase worker nos permite configurar el script para que cada hilo pueda tener su tiempo de ejecución. Como resultado, haremos que los otros subprocesos duerman más tiempo si un subproceso tiene una prioridad más alta.

La clase Worker es una clase MFC simple que lo ayuda con subprocesos múltiples. Cualquier objeto que requiera su subproceso para realizar el trabajo hereda de la clase Trabajador.

Use la función Do-Work para ejecutar el proceso largo y luego use Start/Stop/Pause en el objeto para realizarlo.

Código de ejemplo:

import time
from threading import Thread
from time import sleep


class Worker(Thread):
    def __init__(self, pri):
        Thread.__init__(self)
        self.pri = pri

    def run(self):
        for i in range(20):
            sleep(1.0 * self.pri)
            print(" -thread with priority:", self.pri)


w1 = Worker(1.0)
w2 = Worker(0.75)
w3 = Worker(0.5)
start = time.time()
w1.start()
w2.start()
w3.start()
end = time.time()

Como parte de este paso, hemos inicializado los trabajadores. Después de eso, hemos creado varios hilos con diferentes prioridades.

Los subprocesos de trabajo ahora se ejecutarán de la siguiente manera:

Output exceeds the size limit. Open the full output data in a text editor
 -thread with priority: 0.5
 -thread with priority: 0.75
 -thread with priority: 1.0
 -thread with priority: 0.5
 -thread with priority: 0.75
 -thread with priority: 0.5
 -thread with priority: 1.0
 -thread with priority: 0.5
 -thread with priority: 0.75
 -thread with priority: 0.5
 -thread with priority: 1.0
 -thread with priority: 0.75

En promedio, veremos que los subprocesos con prioridades 0.5 y 0.75 fueron llamados con más frecuencia que los subprocesos con prioridades 1.0 después de la ejecución al observar el seguimiento de salida de la ejecución del subproceso.

El siguiente ejemplo muestra cómo un simple script de Python puede programar un subproceso de Python en función de una prioridad.

Ahora hemos visto algunos ejemplos de subprocesos de Python y cómo crear programas con subprocesos con muchos subprocesos, prioridad de programación y los problemas que resuelven. También se ha demostrado el uso de las clases start(), join(), time(), worker y muchos otros métodos.

Esperamos que este artículo le resulte útil para comprender cómo usar los subprocesos en Python.

Autor: Abid Ullah
Abid Ullah avatar Abid Ullah avatar

My name is Abid Ullah, and I am a software engineer. I love writing articles on programming, and my favorite topics are Python, PHP, JavaScript, and Linux. I tend to provide solutions to people in programming problems through my articles. I believe that I can bring a lot to you with my skills, experience, and qualification in technical writing.

LinkedIn

Artículo relacionado - Python Thread