Sobes.tech
Middle

Kuidas vältida vastastikust lukustamist (deadlock) Go programmis?

sobes.tech AI

Vastus AI-lt

Go-sises vastsavienojums visbiežāk rodas nepareizas mutexu un kanālu izmantošanas dēļ. To var novērst ar šādiem paņēmieniem:

  • Sakārtots mutexu iegūšana: Kad iegūstat vairākus mutexus, vienmēr dariet to tajā pašā secībā visās gorutīnās.
  • Laika ierobežojumi bloķēšanai: Izmantojiet kontekstus ar laika ierobežojumiem, gaidot bloķējumus vai saņemot datus no kanāliem, lai izvairītos no bezgalīgas gaidīšanas.
  • Neaizpildīti kanāli: Saprotiet, ka neaizpildīti kanāli prasa gan sūtītājam, gan saņēmējam būt aktīviem, lai turpinātu izpildi. Nepareiza izmantošana var novest pie bloķēšanas.
  • Aizpildīti kanāli: Pareizi izvēlieties kanāla bufera izmēru. Pārāk mazs buferis var novest pie bloķēšanas, ja sūtītāji un saņēmēji nav sinhronizēti.
  • select izmantošana: Darbojoties ar vairākiem kanāliem, izmantojiet select ar default zaru vai laika ierobežojumu, lai izvairītos no bloķēšanas, gaidot uz vienu kanālu.
  • Koda analīze: Izmantojiet statisko analīzi (go vet, staticcheck) un rīkus datu sacensību noteikšanai (go run -race), kas arī var palīdzēt identificēt potenciālas savstarpējas bloķēšanas vietas.
  • Resursu hierarhija: Ja resursiem ir hierarhija, tos iegūstiet no augšas uz leju.
  • Ciklisks atkarību novēršana: Neizveidojiet situācijas, kur gorutina A gaida resursu, kas ir aizņemts B, bet B gaida resursu, kas ir aizņemts A.

Piemērs, izmantojot select ar laika ierobežojumu:

import (
	"context"
	"time"
)

func piemērs(ch chan int) {
	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
	defer cancel()

	select {
	case val := <-ch:
		// Apstrādāt vērtību
		_ = val
	case <-ctx.Done():
		// Notika laika ierobežojums
	}
}