Corrutina en Python

Requisito previo: Generadores
Todos estamos familiarizados con la función, que también se conoce como subrutina , procedimiento , subproceso , etc. Una función es una secuencia de instrucciones empaquetadas como una unidad para realizar una determinada tarea. Cuando la lógica de una función compleja se divide en varios pasos autónomos que son en sí mismos funciones, estas funciones se denominan funciones auxiliares o subrutinas .

Las subrutinas en Python son llamadas por la función principal que es responsable de coordinar el uso de estas subrutinas. Las subrutinas tienen un solo punto de entrada. 

subroutine

Las corrutinas son generalizaciones de subrutinas. Se utilizan para la multitarea cooperativa en la que un proceso cede voluntariamente (regala) el control periódicamente o cuando está inactivo para permitir que varias aplicaciones se ejecuten simultáneamente. La diferencia entre corrutina y subrutina es:  

  • A diferencia de las subrutinas, las corrutinas tienen muchos puntos de entrada para suspender y reanudar la ejecución. La rutina puede suspender su ejecución y transferir el control a otra rutina y puede reanudar la ejecución desde el punto en que la dejó.
  • A diferencia de las subrutinas, no existe una función principal para llamar a las corrutinas en un orden particular y coordinar los resultados. Las corrutinas son cooperativas, lo que significa que se unen para formar una canalización. Una rutina puede consumir datos de entrada y enviarlos a otra que los procese. Finalmente, puede haber una rutina para mostrar el resultado.

coroutine

Corrutina Vs Hilo

Ahora podrías estar pensando en qué se diferencia la rutina de los subprocesos, ambos parecen hacer el mismo trabajo. 
En el caso de los subprocesos, es un sistema operativo (o entorno de tiempo de ejecución) que cambia entre subprocesos de acuerdo con el planificador. Mientras que en el caso de una rutina, es el programador y el lenguaje de programación los que deciden cuándo cambiar las rutinas. Las corrutinas trabajan cooperativamente en múltiples tareas al suspender y reanudar en puntos establecidos por el programador. 
 

Corrutina de Python

En Python, las corrutinas son similares a los generadores pero con pocos métodos adicionales y ligeros cambios en la forma en que usamos las declaraciones de rendimiento . Los generadores producen datos para la iteración, mientras que las corrutinas también pueden consumir datos. 
En Python 2.5, se introdujo una ligera modificación a la declaración de rendimiento, ahora el rendimiento también se puede usar como una expresión . Por ejemplo, en el lado derecho de la tarea: 

line = (yield)

cualquier valor que enviemos a coroutine es capturado y devuelto por la expresión  (rendimiento) .

Se puede enviar un valor a la corrutina mediante el método send() . Por ejemplo, considere esta rutina que imprime el nombre que tiene el prefijo «Estimado». Enviaremos nombres a coroutine usando el método send(). 

Python3

# Python3 program for demonstrating
# coroutine execution
 
def print_name(prefix):
    print("Searching prefix:{}".format(prefix))
    while True:
        name = (yield)
        if prefix in name:
            print(name)
 
# calling coroutine, nothing will happen
corou = print_name("Dear")
 
# This will start execution of coroutine and
# Prints first line "Searching prefix..."
# and advance execution to the first yield expression
corou.__next__()
 
# sending inputs
corou.send("Atul")
corou.send("Dear Atul")

Producción: 

Searching prefix:Dear
Dear Atul

Ejecución de rutina

La ejecución de la rutina es similar a la del generador. Cuando llamamos a coroutine, no sucede nada, se ejecuta solo en respuesta al método next() y sends () . Esto se puede ver claramente en el ejemplo anterior, ya que solo después de llamar al método __next__() , nuestra corrutina comienza a ejecutarse. Después de esta llamada, la ejecución avanza a la primera expresión de rendimiento, ahora la ejecución se detiene y espera a que se envíe el valor al objeto corou . Cuando se le envía el primer valor, comprueba el prefijo e imprime el nombre si el prefijo está presente. Después de imprimir el nombre, pasa por el ciclo hasta que encuentra la expresión  name = (rendimiento) nuevamente.
 

Cerrar una rutina

Coroutine puede ejecutarse indefinidamente, para cerrar coroutine se usa el método close() . Cuando se cierra una rutina, genera una excepción GeneratorExit que se puede detectar de la forma habitual. Después de cerrar la rutina, si intentamos enviar valores, generará la excepción StopIteration . El siguiente es un ejemplo simple: 

Python3

# Python3 program for demonstrating
# closing a coroutine
 
def print_name(prefix):
    print("Searching prefix:{}".format(prefix))
    try :
        while True:
                name = (yield)
                if prefix in name:
                    print(name)
    except GeneratorExit:
            print("Closing coroutine!!")
 
corou = print_name("Dear")
corou.__next__()
corou.send("Atul")
corou.send("Dear Atul")
corou.close()

Producción: 

Searching prefix:Dear
Dear Atul
Closing coroutine!!

Enstringmiento de rutinas para crear canalizaciones

Las corrutinas se pueden usar para establecer tuberías. Podemos enstringr corrutinas y enviar datos a través de la tubería usando el método send(). Una tubería necesita:  

  • Una fuente inicial (productor) deriva toda la canalización. El productor generalmente no es una rutina, es solo un método simple.
  • Un sumidero , que es el punto final de la tubería. Un sumidero podría recopilar todos los datos y mostrarlos.

pipeline

El siguiente es un ejemplo simple de enstringmiento: 

Python3

# Python3 program for demonstrating
# coroutine chaining
 
def producer(sentence, next_coroutine):
    '''
    Producer which just split strings and
    feed it to pattern_filter coroutine
    '''
    tokens = sentence.split(" ")
    for token in tokens:
        next_coroutine.send(token)
    next_coroutine.close()
 
def pattern_filter(pattern="ing", next_coroutine=None):
    '''
    Search for pattern in received token
    and if pattern got matched, send it to
    print_token() coroutine for printing
    '''
    print("Searching for {}".format(pattern))
    try:
        while True:
            token = (yield)
            if pattern in token:
                next_coroutine.send(token)
    except GeneratorExit:
        print("Done with filtering!!")
 
def print_token():
    '''
    Act as a sink, simply print the
    received tokens
    '''
    print("I'm sink, i'll print tokens")
    try:
        while True:
            token = (yield)
            print(token)
    except GeneratorExit:
        print("Done with printing!")
 
pt = print_token()
pt.__next__()
pf = pattern_filter(next_coroutine = pt)
pf.__next__()
 
sentence = "Bob is running behind a fast moving car"
producer(sentence, pf)

Producción: 

I'm sink, i'll print tokens
Searching for ing
running
moving
Done with filtering!!
Done with printing!

Referencias 

Este artículo es una contribución de Atul 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 *