[Go] Programação simultânea em linguagem Go: princípio, prática e otimização

No mundo da informática atual, os processadores multi-core e a programação simultânea tornaram-se a chave para melhorar a eficiência da execução do programa. Como uma linguagem de programação inovadora, a linguagem Go se destaca nesse aspecto por seus poderosos recursos de simultaneidade. Este artigo irá aprofundar os princípios da programação simultânea em Go, demonstrar sua aplicação por meio de exemplos práticos de código e discutir possíveis estratégias de otimização.

1. Simultaneidade e paralelismo

Antes de entender a programação simultânea na linguagem Go, primeiro precisamos entender a diferença entre simultaneidade e paralelismo. A simultaneidade refere-se à simultaneidade lógica de um programa, ou seja, múltiplas tarefas são executadas alternadamente no tempo, mas do ponto de vista do usuário, essas tarefas parecem ser executadas ao mesmo tempo. O paralelismo refere-se à simultaneidade no nível físico, ou seja, múltiplas tarefas são verdadeiramente executadas simultaneamente.

A capacidade de simultaneidade da linguagem Go é refletida principalmente em seus mecanismos integrados de goroutine e canal. Goroutines são threads leves gerenciados pelo ambiente de execução Go. Usando goroutines, podemos facilmente criar milhões de threads de execução independentes sem impor sobrecarga excessiva ao sistema.

2. Implementação de programação simultânea em linguagem Go

Na linguagem Go, podemos implementar programação simultânea das seguintes maneiras:

Inicie uma nova goroutine com a palavra-chave “go”:

go func() {
    
    
    // 并行执行的代码
}()

Utilize canais de comunicação entre goroutines:

ch := make(chan int)  // 创建一个整型通道
go func() {
    
    
    ch <- 42  // 向通道发送数据
}()
fmt.Println(<-ch)  // 从通道接收数据并打印

Use um mutex (Mutex) para garantir acesso exclusivo aos recursos compartilhados:

var mutex sync.Mutex
var sharedResource int
go func() {
    
    
    mutex.Lock()  // 获取互斥锁
    sharedResource = 42  // 修改共享资源
    mutex.Unlock()  // 释放互斥锁
}()
// 在其他地方读取共享资源
fmt.Println(sharedResource)
使用条件变量(Condition Variable)实现goroutine之间的同步:
go
var cond *sync.Cond
var sharedResource int
cond = sync.NewCond(&sync.Mutex{
    
    })  // 创建一个条件变量,并关联互斥锁
go func() {
    
    
    sharedResource = 42  // 修改共享资源
    cond.Signal()  // 发送信号通知等待的goroutine条件已满足
}()
cond.L.Lock()  // 获取互斥锁,并等待条件满足
for sharedResource == 0 {
    
    
    cond.Wait()  // 等待信号通知,继续循环检查条件是否满足
}
fmt.Println(sharedResource)  // 打印共享资源值

3. Exemplo de código: programa rastreador simultâneo

A seguir está um exemplo simples de implementação de um rastreador simultâneo na linguagem Go. O programa busca o conteúdo da página da web simultaneamente, iniciando vários goroutines e armazena os resultados em um canal. Finalmente, a goroutine principal lê os dados do canal e os processa.

package main

import (
 "fmt"
 "net/http"
 "sync"
)

func fetch(url string, ch chan<- string, wg *sync.WaitGroup) {
    
    
 defer wg.Done()
 resp, err := http.Get(url)
 if err != nil {
    
    
 return
 }
 defer resp.Body.Close()
 ch <- resp.Text()  // 将网页内容发送到channel中
}

func main() {
    
    
 urls := []string{
    
    "http://example.com", "http://example.org", "http://example.net"}
 ch := make(chan string)  // 创建一个字符串通道用于接收网页内容
 var wg sync.WaitGroup    // 用于等待所有爬虫任务完成的计数器
 wg.Add(len(urls))         // 设置计数器的初始值
 for _, url := range urls {
    
    
 go fetch(url, ch, &wg)  // 启动每个爬虫任务,并将结果发送到channel中
 }
 go func() {
    
       // 创建一个辅助goroutine,用于等待所有爬虫任务完成并关闭channel
 wg.Wait()
 close(ch)     // 关闭channel,表示所有数据已发送完毕
 }()
 for data := range ch {
    
      // 从channel中读取每个网页的内容并处理
 fmt.Println(data)   // 这里只是简单地打印网页内容,实际应用中可以根据需求进行进一步处理和存储等操作。
 }
}

Acho que você gosta

Origin blog.csdn.net/qq_22744093/article/details/132467560
Recomendado
Clasificación