Go idioma avanzado Notas de Estudio

corrutina

  1. Crear un defecto cuando una pila de zoom ⼩
  • Después JDK5 Java pila de subprocesos por defecto a 1M
  • Groutine inicialización de la pila zoom ⼩ a 2K
  1. Y la correspondencia entre el KSE (hilos del sistema de espacio del núcleo entidad)
  • Java Tema 是 1: 1
  • Groutine es M: N

Enhebrar el coste de transferencia grande

imagen

imagen

Permítanme hablar de la naturaleza de corrutinas es el modo de usuario hilo, el usuario tiene control de su autoridad, de pequeño tamaño, bajo coste de conmutación.

MPG nuevamente a explicar lo que eso significa.

M significa hilos del núcleo, y todo se debe colocar en M G para correr.

P representa un controlador para programar G M, que mantiene una cola, que se necesita para almacenar toda la G. programado

G representa una rutina de unidad de marcha.

Añadir unas cuantas política de planificación común:

1, si una M en el bloqueo de él?
Cuando un hilo M OS bloqueado debido io en funcionamiento, asumiendo que se ejecutan en el G0 n M, P M que está enlazado al resto de todo llevaría a encontrar un nuevo G M. Cuando se recupera M, en general, tomará el relevo de la otra una P M, y la anteriormente ejecuta la misma G0 P coloca en la cola, corriendo así G0. Si P no está disponible, a continuación, obtener, poner en la cola de cola de ejecución G0 mundial global, en espera de ser programado de manera G0, entonces M entra en el cache de procesos. Todo P comprobará periódicamente el goroutine cola de ejecución global y ejecutarlos, de lo contrario goroutine en la cola de ejecución global nunca ejecutado.

2, si los hay más ocupado H, M y algunos relativamente libre de ella?
Las tareas P y G asignados realizarse rápidamente terminadas (distribución desigual), lo que llevó al procesador P ocupado, P, sino también otras tareas. En este caso, P es el primero en tomar la cola de ejecución global de G. Sin embargo, si no hay tarea cola de ejecución global de G, entonces P tuvo que recoger un poco de otros miembros del G P en llevar a cabo. En general, si P P desde allí para traer otras tareas, el general tomó cola de medio plazo, lo que garantiza que cada hebra de OS puede hacer pleno uso.

3, si una carrera G durante demasiado tiempo, lo que lleva a la cola de G posterior no puede ejecutarlo?
Hora de inicio, se creará un sysmon hilo especial, que se utiliza para controlar y gestionar, dentro de un ciclo. En primer lugar, una tarea de impresión para todos los P G recuentos schedtick, schedtick incrementa después de cada realización de una tarea G. Si el cheque no se ha incrementado a schedtick, lo que indica que P G ha estado implementando la misma tarea, si hay más de un cierto período de tiempo (10 ms), además de una marca en la información de la pila G esta tarea en el interior. Entonces la tarea G en el transcurso de la ejecución, si se encuentra con una llamada a la función dentro de la no-inline, se comprobará por la bandera, a continuación, se interrumpió para añadir a su final de la cola, realice la siguiente G. Si no encuentra una función no-inline (a veces la función normal será optimizado para funcionar en línea pequeña) llamada, entonces era trágica, G siempre se llevará a cabo esta tarea hasta el final de su propia, y si se trata de un ciclo de muerte y GOMAXPROCS = 1, entonces felicitaciones, apisonada en vivo! Pro-test, es cierto.

4, un G porque el horario se interrumpe, entonces cómo restaurar?
Cuando la información de registro de pila de interrupción, guardarlo en su G objetos en su interior. Cuando su turno para actuar de nuevo, copiar la información guardada en el interior pila de registros, por lo que a continuación, después de ejecutar el último. (≧ ▽ ≦) /

func TestGroutine(t *testing.T) {
	for i := 0; i < 10; i++ {
		go func(i int) {
			//time.Sleep(time.Second * 1)
			fmt.Println(i) //值传递,协程间没有竞争关系
		}(i)
	}
	time.Sleep(time.Millisecond * 50)
}

//每次输出顺序不一致

concurrencia de memoria compartida

  • 包paquete de sincronización
    objeto mutex
    rwlock

  • Operación de bloqueo

func TestCounterThreadSafe(t *testing.T) {
	var mut sync.Mutex
	counter := 0
	for i := 0; i < 5000; i++ {
		go func() {
			defer func() {
				mut.Unlock()
			}()
			mut.Lock()
			counter++
		}()
	}
	time.Sleep(1 * time.Second) //等所有协程执行完
	t.Logf("counter = %d", counter)
}
  • WaitGroup sólo después de la finalización de todas las cosas que esperar a realizar abajo
func TestCounterWaitGroup(t *testing.T) {
	var mut sync.Mutex
	var wg sync.WaitGroup
	counter := 0
	for i := 0; i < 5000; i++ {
		wg.Add(1) //新增一个我们要等待的任务
		go func() {
			defer func() {
				mut.Unlock()
			}()
			mut.Lock()
			counter++
			wg.Done() //有一个等待的任务已经完成
		}()
	}
	wg.Wait() //所有要等待的任务都已经完成
	t.Logf("counter = %d", counter)

}

modelo de concurrencia CSP

  • modelo CSP se propone años setenta del siglo pasado, y se utiliza para describir dos entidades separadas a través del canal compartido concurrente de comunicación (tubería) modelo simultáneo de la comunicación. CSP es una primera clase de objetos en el canal, no se refiere a la entidad que envía el mensaje, mientras se utiliza el canal en cuestión al enviar mensajes.
Golang CSP
  • CSP es pedir prestado algunos conceptos modelo Golang los cuales la teoría soporte de concurrencia, de hecho, a partir del hecho, el lenguaje go no se dio cuenta plenamente todo el modelo teórico para la CSP, simplemente tomó prestado el proceso y canalizar estos dos conceptos. entidad de proceso se refleja en el lenguaje que goroutine ir es en realidad la ejecución concurrente, el intercambio de datos se logra a través del canal de comunicación entre cada entidad.
Canal
  • Golang utilizar el concepto de canal de CSP. canal se crea por separado y se puede transferir entre los procesos, su modo de comunicación es similar al modo jefe de trabajo, una entidad mediante el envío de un mensaje al canal, entonces la entidad de proceso de escucha del canal es entre dos entidades anónimo, esta entidad intermedia para lograr la desvinculación, el canal es un mensaje síncrono se envía al canal, la final es seguro para ser consumido otra entidad, de hecho, es la realización del principio de una cola de mensajes de bloqueo.
// 做一个任务service(50ms)
func service() string {
	time.Sleep(time.Millisecond * 50)
	return "Done"
}

// 不相关的任务(100ms)
func otherTask() {
	fmt.Println("working on something else")
	time.Sleep(time.Millisecond * 100)
	fmt.Println("Task is done.")
}

// 这样调用两个任务是串行的
func TestService(t *testing.T) {
	fmt.Println(service())
	otherTask()
	//串行输出任务1,任务2结果
}

/*************** CSP 改进版 ********************/

// 返回结果的时候把channel返回回去,当外面需要的时候可以去channel等待
func AsyncService() chan string {
	retCh := make(chan string) //阻塞性channel
	//retCh := make(chan string, 1) // 非阻塞性
	//启用一个协程去运行
	go func() {
		ret := service()
		fmt.Println("returned result.")
		retCh <- ret //运行完把结果返回到channel,如果其他地方没有取这个消息,整个协程被阻塞,如果用buffer channel则不会被阻塞
		fmt.Println("service exited.")
	}()
	return retCh
}

//
func TestAsynService(t *testing.T) {
	retCh := AsyncService() 
	otherTask() //(结果是这行先被执行好)
	fmt.Println(<-retCh) //需要结果的时候从channel取出数据
	time.Sleep(time.Second * 1)
}

Supongo que te gusta

Origin www.cnblogs.com/jaychan/p/12609100.html
Recomendado
Clasificación