2010-10-17 12 views
9

Los canales combinan la comunicación (el intercambio de un valor) con la sincronización, lo que garantiza que dos cálculos (rutinas) se encuentren en un estado conocido.¿Cómo podemos usar canales en Go en lugar de mutex?

¿Cómo es posible utilizar los canales en Google Go para realizar la funcionalidad de mutex?

package main 

import "sync" 

var global int = 0 
var m sync.Mutex 

func thread1(){ 
    m.Lock() 
    global = 1 
    m.Unlock() 
} 

func thread2(){ 
    m.Lock() 
    global = 2 
    m.Unlock() 
} 

func main(){ 
    go thread1() 
    go thread2() 
} 
+3

Este tipo de pregunta no ve el punto. Debería preguntarse "¿por qué quiero un mutex y cómo puedo usar canales?" –

Respuesta

17

Un ejemplo del uso de un canal como un objeto mutex:

package main 

var global int = 0 
var c = make(chan int, 1) 

func thread1(){ 
    <-c // Grab the ticket 
    global = 1 
    c <- 1 // Give it back 
} 

func thread2(){ 
    <-c 
    global = 2 
    c <- 1 
} 

func main() { 
    c <- 1 // Put the initial value into the channel 
    go thread1() 
    go thread2() 
} 
+0

Gracias por la respuesta MizardX. – Kevin

+0

¡Solución increíble! – HaltingState

+2

Si bien los canales proporcionan una buena solución para los datos protegidos, es una solución menos eficiente en el caso de un escritor y muchos lectores. –

4

Si usted tiene un canal c que inicializar con 1 artículo en él, entonces se puede "check out", el "mutex" quitando el valor de la canal (<-c). Puede "liberarlo" agregando el valor de nuevo (c <- 1).

Dado que el operador extraer-de-canal a) es atómico, yb) bloquea hasta que haya algo que extraer, funciona como un mutex, ya que si un hilo de ejecución ya lo tiene desprotegido, no habrá nada en el canal, y por lo tanto se bloqueará hasta que el hilo que lo tuvo desprotegido devuelva un valor al canal para extraer otro hilo.

+0

Gracias Amber. ¿Podemos tener el ejemplo mostrado anteriormente implementado usando canales en lugar de mutex? – Kevin