Semáforos en Python
En esta guía, aprenderemos cómo manejar subprocesos múltiples en Python usando semáforos. ¿Cómo tener acceso sincronizado a los hilos y la cantidad restringida de recursos?
Semáforos
Un controlador de sincronización es un semáforo. Semaphore proporciona acceso sincronizado a un número limitado de recursos para subprocesos.
Un semáforo se puede ver como una variable que representa cuántos recursos están disponibles ahora.
Por ejemplo, un estacionamiento en un centro comercial que funciona como un semáforo tiene varios espacios disponibles en un nivel determinado.
El valor del semáforo debe ser mayor o menor que los recursos disponibles. Las operaciones de adquirir
y liberar
están conectadas con el semáforo.
El valor del semáforo se reduce cuando un subproceso “adquiere” uno de los recursos que se utilizan para la sincronización. El valor del semáforo aumenta cuando un subproceso “libera” uno de los recursos sincronizados.
Semáforos en Python
La implementación de Python del concepto de semáforo utiliza una clase del módulo threading
. Semáforo
es el nombre de esta clase.
Las funciones acquire()
y release()
están incluidas en la clase Semaphore
, junto con un constructor de funciones.
Si el recuento de semáforos es mayor que cero, se utiliza la función adquirir()
para reducir el recuento. De lo contrario, se bloqueará hasta que el recuento sea mayor que 0.
Uno de los subprocesos que se encuentran en el semáforo se activa mediante el uso de la función release()
, que también aumenta la cuenta del semáforo. Ahora comprendamos la sintaxis del semáforo.
object_name = threading.Semaphore(count)
El objeto de la clase Semáforo
se indica mediante el nombre_objeto
en la sintaxis anterior.
El número de subprocesos a los que se permite acceder a la vez se especifica mediante el argumento recuento
de la clase Semáforo
. El valor predeterminado de este parámetro es 1.
El valor del parámetro contar
se reduce en uno cada vez que un subproceso utiliza la función adquirir()
. El valor del parámetro count
se incrementa en uno cada vez que un hilo utiliza la función release()
.
De acuerdo con esta afirmación, cada vez que llamemos al método adquirir()
, el valor del parámetro contar
disminuirá; sin embargo, cuando llamamos a la función release()
, el valor del parámetro count
aumentará. Echa un vistazo al siguiente código.
# import threading module
import threading
# creating instance of semaphore
sema = threading.Semaphore(1)
def test():
# appling semaphore
print(f"Value Of Semaphore --> {sema._value}")
sema.acquire()
print(f"acquired lock --> {threading.current_thread().name}")
print(f"Value Of Semaphore --> {sema._value}")
print(f"release lock --> {threading.current_thread().name}")
sema.release()
print(f"Value Of Semaphore --> {sema._value}")
# initializing threads
t1 = threading.Thread(target=test)
t2 = threading.Thread(target=test)
t3 = threading.Thread(target=test)
# executing threads
t1.start()
t2.start()
t3.start()
Los subprocesos se sincronizarán si count
se establece en 1, como en el código anterior. Si observamos la salida del código anterior, notaremos que será el primer y segundo subproceso, luego el tercer subproceso tendrá acceso al código entre “adquirir” y “liberar”.
Value Of Semaphore --> 1
Value Of Semaphore --> 1
acquired lock --> Thread-1 (test)
Value Of Semaphore --> 0
Value Of Semaphore --> 0
release lock --> Thread-1 (test)
Value Of Semaphore --> 1
acquired lock --> Thread-2 (test)
Value Of Semaphore --> 0
release lock --> Thread-2 (test)
Value Of Semaphore --> 1
acquired lock --> Thread-3 (test)
Value Of Semaphore --> 0
release lock --> Thread-3 (test)
Value Of Semaphore --> 1
Si tuviera que cambiar el valor del recuento
de 1 a 2, permitiría dos subprocesos al código restringido a la vez. Entonces, la salida será diferente.
Value Of Semaphore --> 2
acquired lock --> Thread-1 (test)
Value Of Semaphore --> 1
Value Of Semaphore --> 1
release lock --> Thread-1 (test)
Value Of Semaphore --> 1
Value Of Semaphore --> 1
acquired lock --> Thread-3 (test)
acquired lock --> Thread-2 (test)
Value Of Semaphore --> 0
Value Of Semaphore --> 0
release lock --> Thread-2 (test)
release lock --> Thread-3 (test)
Value Of Semaphore --> 1
Value Of Semaphore --> 2
Tenga en cuenta que el tiempo que tarda el semáforo en liberar el hilo se basa en la velocidad de su dispositivo, y cada vez será diferente. Puede probar el código anterior cambiando el valor del recuento
en la instancia del semáforo.
Haider specializes in technical writing. He has a solid background in computer science that allows him to create engaging, original, and compelling technical tutorials. In his free time, he enjoys adding new skills to his repertoire and watching Netflix.
LinkedIn