[Golang] aplicación del canal unidireccional de "modelo de consumo productiva".

aplicación canal unidireccional "modelo de consumo productivo"

La aplicación más típico es un canal unidireccional, "modelo productor-consumidor."

El llamado "modelo productor-consumidor": un módulo (función, etc.) responsable de producir los datos, que es responsable de procesar por otro módulo (módulo aquí es amplia, puede ser una clase, función, co-rutina, hilados, procesos etc.). módulo de generación de datos, se llama acertadamente productor; y el módulo de procesamiento de datos, llamado el consumidor.

sólo los productores y consumidores abstractos, pero también lo suficientemente en un modelo productor / consumidor. Este modo también es necesario tener un buffer de entre productores y consumidores, como intermediario. datos del fabricante en el búfer, los datos tomados de la memoria intermedia y el consumidor. Figura estructura aproximada de la siguiente manera:

A modo de ejemplo, enviar una carta a la ayuda en la comprensión de lo que, si desea enviar una carta ordinaria, más o menos como sigue:

  1. La carta escrita - los datos correspondientes a la toma de

  2. La carta en el buzón - datos equivalentes en el búfer Fabricante

  3. Cartero que la carta fue retirado del buzón - recuperación de datos correspondiente tampón para el consumidor

  4. Cartero llevar la carta a la oficina de correos para hacer el tratamiento adecuado - el equivalente de procesamiento de datos de los consumidores

Por lo tanto, este buffer qué sirve? ¿Por qué no llamar a una función directamente a los productores de los consumidores, para pasar datos directamente en el pasado, y para establecer un búfer superflua como él?

Los beneficios de la memoria intermedia, probablemente, de la siguiente manera:

1: El desacoplamiento

Suponiendo que los productores y los consumidores son las dos clases. Si deja que el productor llamando directamente a un método de los consumidores, los consumidores tendrán que depender de los productores (es decir, acoplamiento). Si los consumidores de los futuros cambios en el código pueden tener un impacto directo sobre los productores. Si ambos se basan en un tampón entre los dos no depende directamente del grado de acoplamiento se reduce correspondientemente.

Siguiendo el ejemplo anterior, si el buzón no se utiliza (tampones), la carta debe aplicar directamente al cartero. Entonces usted tiene que saber quién es el cartero. Esta dependencia entre la generación y usted y el cartero (el equivalente a la fuerte acoplamiento de los productores y consumidores). Si un día las sustituciones cartero, usted tiene que volver a reconocer la próxima cartero (modificaciones equivalentes conducen a cambios en el productor al consumidor Código). Mientras que el buzón relativamente fijo, que dependen de ella es un costo relativamente bajo (y que corresponde al acoplamiento débil entre los tampones).

2: El procesamiento simultáneo

Productor consumidores llamar directamente a un método, existen otros inconvenientes. Desde la llamada de función es síncrono (o bloqueo de llamadas), el método no devuelve antes de que los consumidores, los productores habían estado esperando por allí. En caso de que el tratamiento de los datos de consumo es lento, los productores sólo pueden residuos injustificada de tiempo.

Después de usar el productor / modelo de consumo, productores y consumidores pueden ser dos sujetos concurrente independiente. datos del fabricante en el búfer produjeron una pérdida de producción puede ir al siguiente de datos. Básicamente no se basan en la velocidad de procesamiento del consumidor.

De hecho, la mayoría tenía este modelo productor-consumidor, se utiliza principalmente para hacer frente a los problemas de concurrencia.

Ejemplos envían una carta a la vista. Si no hay un buzón de correo, usted tiene que entregar la carta sobre pie tonta en la intersección esperando al cartero a cerrar (el equivalente del productor obstrucción), o si el cartero iba de puerta en puerta para pedir, que enviará una carta (el equivalente de los consumidores encuestados).

3: Cache

Si la velocidad lenta cuando la velocidad del fabricante de los datos, los beneficios de la memoria intermedia se manifiesta. Cuando los datos de fabricación rápida, consumidores de tiempo para el proceso, los datos no procesados ​​pueden ser almacenados temporalmente en la memoria intermedia. Fabricación de velocidad lenta por el productor, consumidor y luego dispuesto lentamente de.

Suponiendo que el cartero sólo puede tener 1000 letra. En el caso de un golpe particular, Día de San Valentín tarjetas de felicitación para enviar, tenemos que enviar una carta de más de 1000, esta vez el buzón Este buffer es muy útil. Cartero demasiado tarde para llevar la carta en el buzón en la puesta en escena, por lo que la próxima vez que se haga cargo.

Por ejemplo:

package main

import "fmt"

// 此通道只能写,不能读。
func producer(out chan<- int)  {
   for i:= 0; i < 10; i++ {
      out <- i*i                // 将 i*i 结果写入到只写channel
   }
   close(out)
}

// 此通道只能读,不能写
func consumer(in <-chan int)  {
   for num := range in {        // 从只读channel中获取数据
      fmt.Println("num =", num)
   }
}

func main()  {
   ch := make(chan int)     // 创建一个双向channel

   // 新建一个groutine, 模拟生产者,产生数据,写入 channel
   go producer(ch)          // channel传参, 传递的是引用。

   // 主协程,模拟消费者,从channel读数据,打印到屏幕
   consumer(ch)             // 与 producer 传递的是同一个 channel
}

Breve descripción: En primer lugar crear un canal de dos vías y, a continuación, abrir una nueva goroutine, el canal bidireccional pasa al método productor como un parámetro, y convertirse en un canales de sólo escritura. Sub corrutina comenzar el ciclo, añadir datos al canal de sólo escritura, que es el productor. corrutina principal, el método de llamada directa al consumidor, que se convertirá en una de sólo lectura canalizar canal bidireccional, mediante la lectura de los datos de cada ciclo del canal, que es el consumidor.

Nota: canal pasado como parámetro se pasa por referencia .

Aquí fabricamos, según el modelo de consumo para simular lo que el orden de procesamiento.

En el desarrollo real, las solicitudes de modelo de productor-consumidor son muy amplios, tales como: el sitio de proveedor de electricidad, procesamiento de pedidos, es un modelo muy típico productor-consumidor.

Cuando muchos usuarios hacen clic en un botón de la orden, orden de producción de todos los datos en la memoria intermedia (cola), y luego el consumidor va a ser sacado de los sistemas de gestión de almacén de datos de cola de remitente.

Por modelo productor-consumidor, se aísla el sistema de orden y el sistema de gestión de almacenes, y el usuario puede ordenar (datos de producción) en cualquier momento. Si el sistema de pedidos llame directamente al sistema de almacén, entonces el usuario hace clic en el botón debajo de la orden de esperar hasta que los resultados del retorno del sistema de almacén. Dicha velocidad será muy lento.

Después de un procesamiento analógico procedimiento en el orden.

package main

import "fmt"

type OrderInfo struct {     // 创建结构体类型OrderInfo,只有一个id 成员
   id int
}

func producer2(out chan <- OrderInfo)  {    // 生成订单——生产者

   for i:=0; i<10; i++ {                // 循环生成10份订单
      order := OrderInfo{id: i+1}
      out <- order                          // 写入channel
   }
   close(out)               // 写完,关闭channel
}

func consumer2(in <- chan OrderInfo)  {       // 处理订单——消费者

   for order := range in {                      // 从channel 取出订单
      fmt.Println("订单id为:", order.id)    // 模拟处理订单
   }
}

func main()  {
   ch := make(chan OrderInfo)  // 定义一个双向 channel, 指定数据类型为OrderInfo
   go producer2(ch)            // 建新协程,传只写channel
   consumer2(ch)               // 主协程,传只读channel
}

De Pedido como información de la orden, aquí por simplicidad sólo se define un número de orden de atributo, a continuación, el producto de simulación productor 10 órdenes, pedidos de los clientes se procesan.

Supongo que te gusta

Origin www.cnblogs.com/liujunhang/p/12536334.html
Recomendado
Clasificación