Bloqueo ordinario Mutex y bloqueo de lectura-escritura RWMutex en idioma Go

1. Bloqueo ordinario Mutex

1.1 Prototipo

escriba Mutex struct {     state int32     sema uint32 }


  • Mutex es un bloqueo mutex que se puede crear como un campo de otras estructuras; el valor cero está desbloqueado. Los bloqueos de tipo mutex no están relacionados con subprocesos y pueden bloquearse y desbloquearse mediante diferentes subprocesos.

1.2 Métodos en Mutex

  • func (m * Mutex) Lock () El
    método de bloqueo bloquea m, si m ya está bloqueado, se bloqueará hasta que m se desbloquee.
  • func (m * Mutex) Unlock () El
    método de desbloqueo desbloquea m.Si m no está bloqueado, provocará un error de tiempo de ejecución. Los bloqueos no tienen nada que ver con los hilos y pueden bloquearse y desbloquearse mediante distintos hilos.

    Caso 1. Use candados comunes para vender boletos en las estaciones de tren
//myMutexTick.go

// myMutexDes project main.go
package main

import (
	"fmt"
	"sync"
	"time"
)

//全局变量
var ticks = 100
var wg sync.WaitGroup
var mutex sync.Mutex

func saleTickets(name string, wg *sync.WaitGroup) {
	for {
		mutex.Lock()
		if ticks > 0 {
			time.Sleep(200 * time.Microsecond)
			fmt.Println(name, ": ", ticks)
			ticks--
		} else {
			fmt.Println(name, "结束卖票...")
			mutex.Unlock()
			break
		}
		mutex.Unlock()
	}
	wg.Done() //通知计数器减一
}

func main() {
	//模拟火车站卖票
	//火车票一共100张,4个售票口出售(相当于4个子协程)

	var wg sync.WaitGroup
	wg.Add(4)
	go saleTickets("售票口A ", &wg)
	go saleTickets("售票口B ", &wg)
	go saleTickets("售票口C ", &wg)
	go saleTickets("售票口D ", &wg)

	wg.Wait()
	fmt.Println("所有车票已售空,程序结束!")
}


    El efecto es el siguiente:


Figura (1) Uso de Mutex para simular la venta de boletos de tren

Dos, bloqueo de lectura y escritura RWMutex

2.1 Prototipo

escriba RWMutex struct {     w Mutex     writerSem uint32     readerSem uint32     readerCount int32     readerWait int32 }





  • RWMutex es un bloqueo mutex de lectura-escritura. El bloqueo puede ser mantenido por varios lectores al mismo tiempo o por un solo escritor. RWMutex se puede crear como un campo de otras estructuras; el valor cero está desbloqueado. Los bloqueos de tipo RWMutex también son independientes de los subprocesos. Diferentes subprocesos pueden agregar bloqueo de lectura / escritura y desbloquear bloqueos de lectura / escritura.
  • Reglas de bloqueo:
    a) En el uso de bloqueos de lectura-escritura: las operaciones de escritura son mutuamente excluyentes, lectura y escritura son mutuamente excluyentes y lectura y lectura no son mutuamente excluyentes.
    b) puede haber una pluralidad de goroutine que lean simultáneamente los datos , pero solo permite una ⼀ goroutine escribir datos .

2.2 Métodos en RWMutex

  • func (rw * RWMutex) Lock () El
    método de bloqueo bloquea rw en el estado de escritura, prohibiendo que otros hilos lean o escriban.
  • func (rw * RWMutex) Unlock () El
    método de desbloqueo desbloquea el estado de bloqueo de escritura de rw.Si m no está bloqueado, provocará un error de tiempo de ejecución.
  • func (rw * RWMutex) RLock () El
    método RLock bloquea rw en un estado de lectura, prohíbe que otros subprocesos escriban, pero no puede ayudar a leer.
  • func (rw * RWMutex) RUnlock ()
    El método Runlock libera el estado de bloqueo de lectura de rw. Si m no agrega bloqueo de lectura, causará un error de tiempo de ejecución.
  • func (rw * RWMutex) RLocker () Locker El
    método Rlocker devuelve un bloqueo de exclusión mutua La interfaz de Locker se realiza llamando a rw.Rlock y rw.Runlock.

    Caso 2. El hilo principal bloquea y desbloquea la subcorutina
//myMutexWrite.go

// myMutexWrite project main.go
package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var rwm sync.RWMutex
	for i := 1; i <= 3; i++ {
		go func(i int) {
			fmt.Printf("goroutine %d, 尝试读锁定", i)
			rwm.RLock()
			fmt.Printf("goroutine %d, 已经读锁定了...\n", i)
			time.Sleep(3 * time.Second)
			fmt.Printf("goroutine %d, 读解锁...\n", i)
			rwm.RUnlock()
		}(i)
	}

	time.Sleep(1 * time.Second)
	fmt.Println("main 尝试写锁定...")
	rwm.Lock()
	fmt.Println("main 已经写锁定了...")
	rwm.Unlock()
	fmt.Printf("main 写解锁...")
}


    El efecto es el siguiente:


Figura (2) El hilo principal bloquea y desbloquea la subcorutina

Supongo que te gusta

Origin blog.csdn.net/sanqima/article/details/108920558
Recomendado
Clasificación