Ir al punto de conocimiento (03): la longitud del canal sin búfer es siempre 0

Veamos primero la longitud del canal de salida del siguiente código.

func main() {
    
    
	ch := make(chan string)
	go func() {
    
    
		ch <- "hello"
		close(ch)
	}()

	time.Sleep(5 * time.Second)
	fmt.Println("ch length is ", len(ch))
	<-ch
}

¿Es 1? La respuesta es: 0, ¿por qué?

Analicemos, primero creemos un canal en la corrutina principal, luego enviemos contenido a este canal en la subcorutina, cierre el canal después del envío y luego esperemos 5 segundos en la corrutina principal, el propósito de esperar es dejar que la subcorutina coroutine La corrutina se puede ejecutar y luego imprimimos la longitud del canal.

Sabemos que para los canales sin búfer, el remitente y el receptor deben estar preparados al mismo tiempo, para que los datos se puedan enviar en el pasado, y en el código anterior primero imprimimos la longitud del canal, y luego el principal Coroutine ya que el receptor recibirá el mensaje del canal Contenido, por lo que cuando imprimimos el canal, debido a que el receptor no está listo para recibir, el remitente siempre está bloqueado. En este momento, el mensaje no ingresa al canal, por lo que el canal la longitud en este momento es 0.

El canal sin búfer no requiere espacio de memoria para almacenar el contenido del mensaje enviado, copia directamente el contenido del mensaje del remitente al receptor cuando el remitente y el receptor están listos.

Cuando el canal de búfer tiene suficiente capacidad, la operación de escritura no se bloqueará. Si está bloqueado o no, depende en gran medida de la operación de lectura. El remitente regresa directamente después de enviar los datos. Esto determina que el canal de búfer necesita una parte de espacio de almacenamiento para almacenar realmente el contenido del mensaje que se enviará.

En el entorno de procesamiento multi-core CPUbajo Gomultiprotocolo, enlazado a múltiples corrutinas en paralelo en la misma channeloperación de lectura de caso, trayendo así el problema del acceso concurrente a los recursos.

Para los canales sin búfer, el remitente y el receptor deben ser operaciones uno a uno, punto a punto. Si hay más de una channeloperación simultánea sin búfer de rutina , entonces se producirá alguna operación de lectura / escritura que no puede coincidir con una operación de escritura / lectura correspondiente que conducirá inevitablemente a un punto muerto.

Para el canal de búfer, desde el Gouso del canal para recibir el mecanismo de bloqueo, es decir, cuando el contenido del canal receptor se toma, primero con el bloqueo del pestillo en el canal, y el acceso a los datos, y luego se libera una vez tomados los datos, asegurando así la pluralidad Asociación Los procedimientos se ejecutan secuencialmente, y no habrá problema de que múltiples corrutinas obtengan los mismos datos en el canal. Cuando una determinada corrutina está recibiendo operaciones, otras corrutinas solo pueden bloquear allí y esperar a la corrutina anterior. Suelte el bloqueo, así garantizar la seguridad de la concurrencia de los datos del canal.

De manera similar, el remitente también sigue este mecanismo de bloqueo, lo que garantiza que solo una corrutina pueda operar el canal al mismo tiempo.

Supongo que te gusta

Origin blog.csdn.net/wohu1104/article/details/115363234
Recomendado
Clasificación