La concurrencia es un aspecto crucial del desarrollo de software moderno, ya que permite que los programas manejen de manera eficiente múltiples tareas simultáneamente. Puede escribir programas que ejecuten varias operaciones que mejoren el rendimiento, la capacidad de respuesta y la utilización de recursos.
La concurrencia es una de las características responsables de la rápida adopción de Go. El soporte incorporado de Go para la programación concurrente se considera sencillo y ayuda a evitar errores comunes como condiciones de carrera y puntos muertos.
Concurrencia en Go
Go proporciona un soporte sólido para la concurrencia a través de varios mecanismos, todos disponibles en su biblioteca y cadena de herramientas estándar. Los programas go logran la concurrencia a través de gorutinas y canales.
Las Goroutines son funciones ligeras que se ejecutan de forma independiente y se ejecutan simultáneamente con otras Goroutines dentro del mismo espacio de direcciones. Goroutines permite que múltiples tareas progresen simultáneamente sin una gestión de subprocesos explícita. Las Goroutines son más ligeras que los subprocesos del sistema operativo y Go puede ejecutar eficientemente miles o incluso millones de Goroutines simultáneamente.
Los canales son el mecanismo de comunicación para la coordinación y el intercambio de datos entre rutinas. Un canal es un conducto tipado que permite a las rutinas enviar y recibir valores. Los canales brindan sincronización para garantizar el intercambio seguro de datos entre goroutines al tiempo que previenen las condiciones de carrera y otros problemas comunes de concurrencia.
Al combinar rutinas y canales, Go proporciona un modelo de concurrencia potente y sencillo que simplifica el desarrollo de programas concurrentes al mismo tiempo que mantiene la seguridad y la eficiencia. Estos mecanismos le permiten usar fácilmente procesadores multinúcleo y crear aplicaciones altamente escalables y receptivas.
Cómo usar Goroutines para la ejecución simultánea de código
El tiempo de ejecución de Go administra goroutines. Goroutines tiene su pila, lo que les permite tener una huella ligera con un tamaño de pila inicial de unos pocos kilobytes.
Las rutinas Gor se multiplexan en varios subprocesos del sistema operativo mediante el tiempo de ejecución de Go. El programador de tiempo de ejecución de Go los programa en subprocesos disponibles mediante la distribución eficiente de la carga de trabajo, lo que permite la ejecución simultánea de varias gorutinas en menos subprocesos del sistema operativo.
Crear goroutines es sencillo. Usarás el ir palabra clave seguida de una llamada de función para declarar goroutines.
Cuando el programa invoca funcion1() y funcion2() con el ir palabra clave, el tiempo de ejecución de Go ejecuta las funciones simultáneamente como rutinas.
Aquí hay un ejemplo de uso de una gorutina que imprime texto en la consola:
El imprimirTexto La función imprime repetidamente algún texto en la consola con un para bucle que se ejecuta cinco veces después de un retraso de un segundo entre cada declaración con el paquete de tiempo.
El principal la función inicia una gorutina llamando ir a imprimirTextoque pone en marcha el imprimirTexto función como una gorutina concurrente separada que permite que la función se ejecute simultáneamente con el resto del código en el principal función.
Finalmente, para asegurarse de que el programa no se cierra antes de que imprimirTexto gooutine termina, el tiempo de dormir La función pausa la rutina principal durante seis segundos. En escenarios del mundo real, usaría mecanismos de sincronización como canales o grupos de espera para coordinar la ejecución de rutinas.
Uso de canales de comunicación y sincronización
Goroutines tiene soporte integrado para la comunicación y sincronización a través de canales, lo que hace que escribir código concurrente sea más fácil que los hilos tradicionales, que a menudo requieren mecanismos de sincronización manual como bloqueos y semáforos.
Puede pensar en los canales como conductos para el flujo de datos entre rutinas. Una gorutina puede enviar un valor al canal y otra gorutina puede recibir ese valor del canal. Este mecanismo garantiza que el intercambio de datos sea seguro y sincronizado.
Usarás el operador para enviar y recibir datos a través de canales.
Aquí hay un ejemplo que demuestra el uso básico de los canales para la comunicación entre dos rutinas:
El canal en el principal función es un canal sin búfer llamado ch creado con el hacer() función. La primera rutina envía el mensaje "¡Hola, canal!" en el canal usando el operador, y la segunda rutina recibe el mensaje del canal usando el mismo operador. Finalmente, el principal La función imprime el mensaje recibido en la consola.
Puede definir canales escritos. Deberá especificar el tipo de canal en el momento de la creación. Aquí hay un ejemplo que demuestra el uso de diferentes tipos de canales:
El principal La función crea dos canales: ch1 es un canal entero sin búfer, mientras que ch2 es un canal de cadena almacenado en búfer con una capacidad de 3. Puede enviar y recibir valores hacia y desde estos canales usando el operador (los valores tienen que ser del tipo especificado).
Puede usar los canales como mecanismos de sincronización para coordinar la ejecución de rutinas aprovechando la naturaleza de bloqueo de las operaciones del canal.
El ch el canal es booleano. Dos goroutines se ejecutan simultáneamente en el principal función. Goroutine 1 señala su finalización mediante el envío de un verdadero valor en el canal ch. Goroutine 2 espera la señal de finalización al recibir un valor del canal. Finalmente, la rutina principal espera la señal de finalización de la rutina dos.
Puede crear aplicaciones web en Go With Gin
Puede crear aplicaciones web de alto rendimiento en Go con Gin mientras aprovecha las funciones de simultaneidad de Go.
Puede usar Gin para manejar el enrutamiento HTTP y el middleware de manera eficiente. Aproveche el soporte de simultaneidad incorporado de Go mediante el empleo de rutinas y canales para tareas como consultas de bases de datos, llamadas a API u otras operaciones de bloqueo.
