minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Goroutines são executadas no mesmo espaço de endereço, portanto o acesso à memória compartilhada deve ser sincronizado.Goroutines compartilham memória por meio da comunicação, em vez de compartilhar memória.
O canal do tipo de referência é uma implementação específica do modo CSP e é usado para comunicação com múltiplas goroutines. Ele implementa a sincronização internamente para garantir a segurança da simultaneidade.
Assim como o mapa, o canal também é uma referência à estrutura de dados subjacente criada por make.
Quando copiamos um canal ou o usamos para passagem de parâmetros de função, apenas copiamos uma referência de canal, para que o chamador e o receptor façam referência ao mesmo objeto de canal. Como outros tipos de referência, o valor zero do canal é nulo.
Ao definir um canal, você também precisa definir o tipo de valores enviados ao canal. Canais podem ser criados usando a função integrada make():
make (chan Type)
make (chan Type,capacity)
channel<-value //发送value 到channel
<-channel //接收并将其丢弃
x:=<-channel //从 channel 中接收数据,并賦偵给x
x,ok:=<-channel //功能同上,同时检查通道是否已关闭或者是否为空
Por padrão, o canal bloqueia ao receber e enviar dados, a menos que a outra extremidade esteja pronta, simplificando a sincronização da goroutine sem a necessidade de bloqueios explícitos.
Um canal sem buffer é um canal que não tem capacidade de salvar nenhum valor antes de receber.
Este tipo de canal requer que a goroutine de envio e a goroutine de recebimento estejam prontas ao mesmo tempo para concluir as operações de envio e recebimento. Se duas goroutines não estiverem prontas ao mesmo tempo, o canal fará com que a goroutine que executa primeiro a operação de envio ou recebimento seja bloqueada e espere.
Esta interação de envio e recebimento no canal é inerentemente síncrona. Nenhuma operação pode existir independentemente da outra.
A figura a seguir mostra como duas goroutines podem compartilhar um valor usando canais sem buffer:
make (chan Type)//等价于make (chan Type,0)
Se nenhum tamanho de buffer for especificado, o canal será síncrono e, portanto, será bloqueado até que o remetente esteja pronto para enviar e o receptor esteja pronto para receber.
Um canal com buffer é um canal que pode armazenar um ou mais valores antes de serem recebidos.
Este tipo de canal não exige que a goroutine conclua o envio e o recebimento ao mesmo tempo. Os canais também terão condições diferentes que bloqueiam ações de envio e recebimento. A ação de recebimento só será bloqueada se não houver valor no canal a ser recebido. A ação de envio só será bloqueada se o canal não tiver buffer disponível para acomodar o valor que está sendo enviado.
Isso leva a uma grande diferença entre canais com buffer e sem buffer: canais sem buffer garantem que o envio e o recebimento de goroutines troquem dados ao mesmo tempo: os canais com buffer não têm essa garantia.
make (chan Type,capacity)
Se for fornecida uma capacidade de buffer, o canal é assíncrono. Enquanto o buffer tiver espaço não utilizado para envio de dados ou contiver dados que possam ser recebidos, a comunicação prosseguirá sem bloqueio.
O canal pode usar ok para detectar se o canal ainda está aberto. Se o canal estiver fechado, os dados não serão lidos.
num ,ok:=<-ch
Pode detectar se um canal está fechado.Por padrão, o canal é de pergunta dupla, ou seja, você pode enviar e receber dados dele.
Porém, muitas vezes vemos um canal passado como parâmetro e espera-se que o valor seja usado em uma direção, seja apenas para enviar dados ou apenas para receber dados. Neste momento, podemos especificar a direção do canal. A declaração de uma variável chamel unidirecional é muito simples, como segue:
var ch1 chan int //ch1双向
var ch2 chan<-float64 //ch2单向,只能用于写float64数据
var ch3 <-chan int //ch3单向,只能用于读int数据
chan<- significa que os dados entram no canal e os dados são gravados no canal, que é enviado para o chamador.
<-chan indica que os dados saem do canal. Para o chamador, os dados do canal são obtidos, que é obviamente a entrada.
Um canal pode ser convertido implicitamente em uma fila unidirecional, recebendo apenas ou apenas enviando, mas um canal unidirecional não pode ser convertido em um canal normal;