Programação simultânea em Go language_Channel

Introdução ao canal

O modelo de simultaneidade da linguagem Go, CSP (Communicating Sequential Processes), defende o compartilhamento da memória por meio da comunicação em vez do compartilhamento da memória.

Embora você possa usar a memória compartilhada para troca de dados, a memória compartilhada está sujeita a condições de corrida em diferentes goroutines. Para garantir a exatidão da troca de dados, um mutex deve ser usado para bloquear a memória, o que pode causar problemas de desempenho.

  • channel: É o mecanismo de comunicação na linguagem Go que envia a uma goroutine um valor específico para outra goroutine.
    O canal na linguagem Go é um tipo especial. Um canal é uma fila que sempre segue a regra do primeiro a entrar, primeiro a sair (Primeiro a entrar, primeiro a sair) para garantir a ordem de envio e recebimento de dados. Cada canal é um tipo específico de conduíte, ou seja, quando você declara o canal, é necessário especificar o tipo de elemento para ele.

Uso do canal

tipo de canal

  • Canal é um tipo de referência. O formato para declarar um canal é o seguinte:
var 变量 chan 元素类型
-------------------------
    var ch1 chan int   // 声明一个传递整型的通道
    var ch2 chan bool  // 声明一个传递布尔型的通道
    var ch3 chan []int // 声明一个传递int切片的通道

Criar canal

Uma vez que o canal é um tipo de referência, o valor padrão do canal é nulo

	var ch1 chan int
	fmt.Println(ch1)//<nil>

Depois que o canal é declarado, ele precisa ser inicializado com a função make antes que possa ser usado.
A sintaxe do make para inicializar o canal é:

    make(chan 元素类型, [缓冲大小])

Canal de operação

O canal tem três operações: tanto o 发送,接收,关闭
envio quanto o recebimento são usados:<-

	ch1 := make(chan int)
	ch1 <- 10//将10发送到ch1中
	x :=<-ch1 //从ch1接收值并赋给x

desligar:

close(ch1)

Nota: Não é necessário fechar o canal. O canal só precisa ser fechado quando a goroutine do receptor for notificada que todos os dados foram enviados. O canal pode ser coletado como lixo.
Enviar valores ou fechar operações para um canal fechado causará pânico.
O valor recebido de um canal fechado pode ser levado ao valor até que o canal esteja vazio, e quando o canal não tiver valor, então o valor obtido só pode ser o valor zero do tipo correspondente.

Canal sem buffer

Insira a descrição da imagem aqui
Canais sem buffer também são chamados de canais bloqueados:

	ch1 := make(chan int)
	ch1 <- 10//将10发送到ch1中

Ao ch1 := make(chan int)criar um canal sem buffer, o canal sem buffer só pode enviar valores quando o receptor existe, caso contrário, ocorrerá um erro de deadlock.

fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()

Existem duas soluções:

  1. Comece um goroutine para receber
func recvdata(c chan int)  {
    
    
	data :=<-c
	fmt.Println("接收成功data",data)
}
func main() {
    
    
	//var ch1 chan int
	//fmt.Println(ch1)
	ch1 := make(chan int)
	go recvdata(ch1)//启动goroutine接收通道里面的值
	ch1<-10//发送10
	fmt.Println("发送成功")
}

同步通道: A operação de envio no canal sem buffer será bloqueada até que outro goroutine execute a operação de recebimento no canal, então o valor pode ser enviado com sucesso e os dois goroutines continuarão a executar. Ao contrário, se a operação de recepção for executada primeiro, a goroutine do receptor será bloqueada até que outra goroutine envie um valor para o canal.
O uso de canais sem buffer para comunicação resultará na sincronização das goroutines de envio e recebimento. Portanto, os canais sem buffer também são chamados de canais síncronos.

Canal de buffer

Um canal com buffer também é uma solução para o problema de um canal sem buffer.
Insira a descrição da imagem aqui
Contanto que a capacidade do canal seja maior que zero, o canal é um canal com buffer. A capacidade do canal indica o número de elementos que podem ser armazenados no canal.
Crie um canal em buffer:

  ch := make(chan int, 1) // 创建一个容量为1的有缓冲区通道

Não haverá situação de impasse desta forma. E esses dados também existem neste canal para armazenamento em buffer.

Canal unilateral

Um canal unilateral é fornecido no idioma Go para restringir os dados a serem enviados ou recebidos apenas

  1.chan<- int是一个只能发送的通道,可以发送但是不能接收;
  out chan <-int
  2.<-chan int是一个只能接收的通道,可以接收但是不能发送。
  in <-chan int

Um canal bidirecional pode ser alterado para unilateral, mas um canal unilateral não pode ser alterado para bidirecional.

Acho que você gosta

Origin blog.csdn.net/H1517043456/article/details/112986275
Recomendado
Clasificación