Cond en sincronización de simultaneidad Go

package main 

import ( 
   "fmt" 
   "sync" 
   "time" 
) 
/** 
 * Cond como rutina 
 */ 
func main() { 
   var lc = new(sync.Mutex) 
   //¿Por qué este casillero pasa una referencia? 
   var cond = sync.NewCond(lc) 


   for i := 0;i < 5;i++ { 
      go func(x int) { 
         cond.L.Lock() 
         defer cond.L.Unlock() 
         cond.Wait() 
         fmt. Printf("el valor es %d\n",x) 
      }(i) 
   } 
   //Duerme un rato, asegúrate de que uno de los siguientes Signal() pueda ser notificado (¿podría no ser notificado?) 
   time.Sleep( 2*tiempo. Segundo) 

   for i:=0;i<3;i++{ 
      fmt.Printf("Activar el proceso de %dth go\n", i) 
      cond.Signal()
      time.Sleep(time.Second*1)
   } 
   fmt.Println("Despertar a todos") 
   cond.Broadcast() 
   time.Sleep(2*time.Second) 
}

//-----------------------apagar----------------------- -

Activar el
valor del proceso GO 0 es 1
activar el
valor del proceso GO 1 es 0 activar el valor
del proceso GO 2 es 3 activar todos los valores es 2 el valor es 4



 

 

En el proceso go, Cond adquiere el bloqueo por separado y se encuentra en estado de espera. La razón por la que puede adquirir un bloqueo de memoria en el proceso go depende del diseño de memoria del lenguaje go.

Llame a Wait() para adquirir el bloqueo por separado e ingrese a la cola de espera.

func (c *Cond) Wait() {//Wait opera con punteros, apuntando a la memoria 
   c.checker.check() 
   t := runtime_notifyListAdd(&c.notify)//Vea el nombre para saber el significado, active Cond Attributes se agregan a la cola de reactivación 
   cLUnlock()//Release por un corto tiempo aquí, y colocan el puntero del atributo clave de Cond en la cola de espera, 
   runtime_notifyListWait(&c.notify, t) 
   cLLock() 
}

Una comprensión de por qué se requiere la liberación de bloqueo aquí: ¿no puede el que espera el tiempo de ejecución ser un Ctrip que mantiene el bloqueo? ? ? ? ?

func (c *copyChecker) check() {//La función de este verificador es que la dirección del puntero y la referencia del valor de c sea la misma, si el paso es el mismo, significa que se ha copiado. 
   if uintptr(*c) != uintptr(unsafe.Pointer(c)) && 
      !atomic.CompareAndSwapUintptr((*uintptr)(c), 0, uintptr(unsafe.Pointer(c))) && 
      uintptr(*c) ! = uintptr(unsafe. Pointer(c)) { 
      panic("sync. Cond is copy") 
   } 
}

Tanto el proceso de Signl como el de Broadcast utilizan el mismo puntero para indicar el método de tiempo de ejecución de la llamada, lo que demuestra que utilizan el mismo puntero como marca para el almacenamiento en espera. En cuanto a por qué puede tener tal efecto, se necesita un desarrollo de seguimiento.

Supongo que te gusta

Origin blog.csdn.net/weixin_40669549/article/details/88544181
Recomendado
Clasificación