¿Python tiene algún equivalente a los canales de múltiples productores y un consumidor (MPSC) de Rust?
Me gustaría tener una función en Python que cree un par de canal de transmisión / recepción con el mismo o un mecanismo similar al de Rust:
Estos canales tienen dos variantes:
- Un canal asincrónico con buffer infinito. La función [
channel
] devolverá una tupla(Sender, Receiver)
en la que todos los envíos serán asincrónicos (no bloqueantes). El canal conceptualmente tiene un buffer infinito.Un canal sincrónico con límite de capacidad. La función [
sync_channel
] devolverá una tupla(SyncSender, Receiver)
en la que el almacenamiento para los mensajes pendientes es un buffer preasignado de tamaño fijo. Todos los envíos serán sincrónicos, es decir, bloquearán hasta que haya espacio en el buffer disponible. Se permite un límite de 0, lo que hace que el canal se convierta en un canal de “reunión” donde cada remitente entrega atómicamente un mensaje a un receptor.[
channel
]: https://doc.rust-lang.org/std/sync/mpsc/fn.channel.html
[sync_channel
]: https://doc.rust-lang.org/std/sync/mpsc/fn.sync_channel.html
davy.ai
Para crear una función en Python que cree un par de canal de transmisor/receptor con el mismo o similar mecanismo que Rust, podemos hacer uso del módulo
queue
, el cual proporciona una implementación segura para hilos de una cola.Para un canal asincrónico con buffer infinito, podemos utilizar la clase
Queue
del móduloqueue
sin especificar un tamaño máximo, lo cual lo hace infinito. Aquí tienes un ejemplo de implementación:La función
canal()
retorna una tupla de dos funciones, la primera funciónq.put
se utiliza para enviar mensajes al canal y nunca se bloquea, mientras que la segunda funciónq.get
se utiliza para recibir mensajes del canal y se bloquea hasta que haya un mensaje disponible.Para un canal síncrono y acotado, podemos utilizar nuevamente la clase
Queue
, pero esta vez especificaremos un tamaño máximo, lo cual creará un búfer de tamaño fijo. Aquí tienes un ejemplo de implementación:La función
canal_sincronizado()
también retorna una tupla de dos funciones, la primera funciónq.put
se utiliza para enviar mensajes al canal y se bloquea hasta que haya espacio en el búfer, y la segunda funciónq.get
se utiliza para recibir mensajes del canal y se bloquea hasta que haya un mensaje disponible.Nota que podemos establecer el parámetro
tamaño
en 0 para crear un canal de encuentro, lo cual hará que cada transmisor entregue atómicamente un mensaje a un receptor.