Recibe elementos de un canal nulo, la actual rutina bloqueará
Enviar elementos a un canal nulo, la gotoutine actual también bloqueará
Enviar un elemento a un canal cerrado provocará un pánico en tiempo de ejecución, incluso si la operación de envío está bloqueada porque el canal está lleno.
Cuando varias goroutinas envían bloqueo de elementos al mismo canal completo, cuando el canal tiene espacio libre, la primera goroutina bloqueada se despertará primero.
Cuando varias gorutinas reciben el bloqueo de elementos del mismo canal vacío, cuando el canal tiene elementos, la primera rutina bloqueada se despertará primero.
Ir solo despierta una gota a la vez.
El valor enviado por el remitente al canal se copia y el receptor siempre recibe una copia del valor.
El valor pasado por el canal se copiará al menos una vez y como máximo dos veces.
Por ejemplo, cuando se copia una vez y se envían elementos a un canal vacío, y ya hay al menos un receptor en espera de recibir, el canal omitirá su propia cola de búfer y copiará directamente al primer receptor en espera de recibir.
Tales como: copiar dos veces, recibir elementos de un canal completo y al menos un remitente está esperando el envío, el canal copiará el elemento ingresado más temprano en la cola del búfer al receptor y luego enviará los primeros datos del remitente Copiar a una ubicación vacía.
Cuando el receptor recibe un valor de tipo de valor del canal, la modificación de este valor no afectará el valor fuente que posee el emisor;
Cuando el receptor recibe un valor de tipo de referencia del canal, la modificación del valor afectará el valor fuente que posee el emisor;
package main
import (
"fmt"
//"time"
)
type dataItem struct {
curl string
paramReq interface{}
resp chan error
}
type metaset struct {
key string
value string
uid string
path string
}
var dataChan = make(chan interface{}, 1)
/*
syncChan1和syncChan2的元素类型都是 struct{},struct{}代表不含任何字段的结构体类型(空结构体)
空结构体变量不占内存空间,所以所有该类型的变量都拥有相同的内存地址。
建议用于传递信号的通道都用struct{}作元素类型,除非需要传递更多的元素。
*/
func main() {
syncChan := make(chan struct{}, 2)
go func() {
for {
if elem, ok := <-dataChan; ok {
if elem, ok := elem.(dataItem); ok {
elem.resp <- nil
fmt.Printf("elem:%v\n", elem)
fmt.Printf("elem.paramReq:%v\n", elem.paramReq)
} else {
fmt.Printf("error")
}
} else {
break
}
}
fmt.Println("stopped.[receiver]")
syncChan <- struct{}{}
}()
go func() {
meta := metaset{key: "key1", value: "value1", uid: "00", path: "/root/dir1"}
data := &dataItem{curl: "/api/test", paramReq: meta, resp: make(chan error, 1)}
for i := 0; i < 5; i++ {
dataChan <- *data
//time.Sleep(time.Second)
fmt.Printf("The count map:%v.[sender]\n", data)
res := <-data.resp
fmt.Println("res:", res)
}
close(dataChan)
syncChan <- struct{}{}
}()
<-syncChan
<-syncChan
}
El resultado:
elem:{/api/test {key1 value1 00 /root/dir1} 0xc042034120}
elem.paramReq:{key1 value1 00 /root/dir1}
The count map:&{/api/test {key1 value1 00 /root/dir1} 0xc042034120}.[sender]
res: <nil>
elem:{/api/test {key1 value1 00 /root/dir1} 0xc042034120}
elem.paramReq:{key1 value1 00 /root/dir1}
The count map:&{/api/test {key1 value1 00 /root/dir1} 0xc042034120}.[sender]
res: <nil>
elem:{/api/test {key1 value1 00 /root/dir1} 0xc042034120}
elem.paramReq:{key1 value1 00 /root/dir1}
The count map:&{/api/test {key1 value1 00 /root/dir1} 0xc042034120}.[sender]
res: <nil>
elem:{/api/test {key1 value1 00 /root/dir1} 0xc042034120}
elem.paramReq:{key1 value1 00 /root/dir1}
The count map:&{/api/test {key1 value1 00 /root/dir1} 0xc042034120}.[sender]
res: <nil>
elem:{/api/test {key1 value1 00 /root/dir1} 0xc042034120}
elem.paramReq:{key1 value1 00 /root/dir1}
The count map:&{/api/test {key1 value1 00 /root/dir1} 0xc042034120}.[sender]
res: <nil>
stopped.[receiver]