介绍
在这篇文章中,我们将仅提及提供的众多工具中的3个
进行例程
首先了解它们的状况以及golang的日常工作的工作方式,在post anterior中写了这一点。
运河
从常规(轻虚拟线程)开始,频道是他们的名称为美,这些例程之间的通信渠道,这是一个强大的工具,因为当我们开始并行执行我们的例程时,有时我们会发现我们自己需要在这些例程之间共享资源。
首先,Golang同意的口号是“不传达共享内存,在交流时共享内存。”
话虽如此,我们可以从以下示例开始,该示例说明了GO通道的操作:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
messages := make(chan string)
// Acá se ejecuta la rutina y se pasa el canal
go sendString(messages)
// Acá se recibe el valor que se envío por el canal
// Y se guarda en la variable msg
msg := <-messages
// Mientras esperamos recibir algo en el canal `messages` el thread queda bloqueado
fmt.Printf("Message received %s", msg)
fmt.Println("Another actions...")
}
func sendString(msg chan string) {
text := readFromConsole()
// Dentro del canal, enviamos el valor por el canal
// Y seguimos el hilo de nuestra rutina
msg <- text
}
func readFromConsole() string {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
return text
}
在此示例中,我们查看我们的Mâ何时所有kude0传递到kude1通道通道频道我们读取的文本的值。然后,在接收该值时,在main
函数的主线程中,我们解锁被阻止的主线程。
等待小组
我们必须警告我们的小组每个例程完成。
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var resp1 string
var resp2 string
// Declaramos nuestro WaitGroup
wg := sync.WaitGroup{}
// Avisamos que el límite será 2 rutinas
wg.Add(2)
go func() {
resp1 = askToService1()
// Avisamos que esta rutina terminó
wg.Done()
}()
go func() {
resp2 = askToService2()
// Avisamos que esta rutina terminó
wg.Done()
}()
// Esperamos a que las ejecuciones terminen
wg.Wait()
// Seguimos la ejecución
fmt.Printf("Response 1: %s\n", resp1)
fmt.Printf("Response 2: %s\n", resp2)
fmt.Println("Another actions...")
}
func askToService1() string {
time.Sleep(3 * time.Second)
return "Hello"
}
func askToService2() string {
time.Sleep(4 * time.Second)
return "Bye bye"
}
这是我们在我的一项工作经验中发展的一个实际情况,因此这是使用Kude3的实用而具体的案例。
互斥
Mutex是开始避免职业条件的操作系统执行的挂毯,我们将要做的是创建Mutex,以了解何时由另一个执行线程访问资源。通过这种方式,我们阻止了一个资源,如果资源已经被阻止,我们将等待它可用。
package main
import (
"fmt"
"sync"
)
type Service struct {
// Este mutex será el que bloquee el recurso `counters`
mu sync.Mutex
counters map[string]int
}
func (svc *Service) increase(counterName string) {
// Acá es donde bloqueamos el recurso
// En caso de estar bloqueado por otra rutina, esperamos hasta desbloquearlo
svc.mu.Lock()
// El defer nos permite ejecutar el comando al terminar la función
// Y con el mutex.Unlock() desbloqueamos el recurso
defer svc.mu.Unlock()
svc.counters[counterName]++
}
func (svc *Service) doIncrement(name string, limit int) {
for i := 0; i < limit; i++ {
svc.increase(name)
}
}
func main() {
c := Service{
counters: map[string]int{"counterA": 0, "counterB": 0},
}
var wg sync.WaitGroup
wg.Add(3)
go func() {
c.doIncrement("counterA", 1000)
wg.Done()
}()
go func() {
c.doIncrement("counterA", 1000)
wg.Done()
}()
go func() {
c.doIncrement("counterB", 1000)
wg.Done()
}()
wg.Wait()
fmt.Println(c.counters)
}
在示例中,它显示了如何同时访问Kude6 2次,以免踩到其价值,Kouude7将等到资源解锁。
结论
在这篇文章中,我们回顾了一些同时管理的GO工具,但是还有其他一些工具我们可能会在以后看到。您自己,我计划输入有关这些工具的更多详细信息,因此我建议您订阅并专注于以下文章ð§