Sobes.tech
Middle

რა ტიპის მუტექსებს უზრუნველყოფს Go-ს სტანდარტული ბიბლიოთეკა?

sobes.tech AI

პასუხი AI-სგან

სტანდარტული ბიბლიოთეკა Go-ის sync პაკეტში ორი ძირითადი ტიპის მუტექსს უზრუნველყოფს:

  • sync.Mutex: ძირითადი მუტექსი, რომელიც უზრუნველყოფს ურთიერთგამორიცხვას. შეიძლება იყოს ორი მდგომარეობა: დაბლოკილი ან განბლოკილი. მხოლოდ ერთი გორუტინა შეუძლია ამჟამად მისი შენარჩუნება.
  • sync.RWMutex: წაკითხვა/წერილის მუტექსი. საშუალებას აძლევს რამდენიმე გორუტინას ერთდროულად წაიკითხოს მონაცემები (RLock-ით), მაგრამ მხოლოდ ერთს წეროს (Lock-ით). წერილი ბლოკავს ყველა ოპერაციას (მათ შორის წაკითხვას და წერას).

sync.Mutex-ის ძირითადი მეთოდები:

მეთოდი აღწერა
Lock() დაბლოკავს მუტექსს. თუ ის უკვე დაბლოკილია, გამშვებ გორუტინას დაელოდება მის გათავისუფლებას.
Unlock() გათავისუფლებს მუტექსს. პანიკა მოხდება, თუ მუტექსი არ იყო დაბლოკილი გამშვებ გორუტინას მიერ.

sync.RWMutex-ის ძირითადი მეთოდები:

მეთოდი აღწერა
Lock() დაბლოკავს მუტექსს წერილისთვის. ბლოკავს ყველა წაკითხვას და წერას ოპერაციას.
Unlock() გათავისუფლებს მუტექსს წერილისთვის. პანიკა მოხდება, თუ ის არ იყო დაბლოკილი წერილისთვის.
RLock() დაბლოკავს მუტექსს წაკითხვისთვის. არ ბლოკავს სხვა წაკითხვებს. ბლოკირდება, თუ წერილის მუტექსი დაბლოკილია.
RUnlock() გათავისუფლებს მუტექსს წაკითხვისთვის. პანიკა მოხდება, თუ ის არ იყო დაბლოკილი წაკითხვისთვის.
RLocker() აბრუნებს Locker-ს, რომელიც იყენებს RLock-ს და RUnlock-ს.

sync.Mutex-ის გამოყენების მაგალითი:

package main

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

var counter int
var mutex sync.Mutex

func increment() {
	mutex.Lock() // დაბლოკეთ მუტექსი
	counter++
	fmt.Printf("Counter: %d\n", counter)
	mutex.Unlock() // გათავისუფლეთ მუტექსი
}

func main() {
	for i := 0; i < 10; i++ {
		go increment()
	}
	time.Sleep(time.Second) // დაელოდეთ გორუტინების დასრულებას
}

sync.RWMutex-ის გამოყენების მაგალითი:

package main

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

var data string
var rwMutex sync.RWMutex

func readData() {
	rwMutex.RLock() // წაკითხვისთვის დაბლოკეთ
	fmt.Printf("მონაცემების წაკითხვა: %s\n", data)
	rwMutex.RUnlock() // გათავისუფლეთ წაკითხვისთვის
}

func writeData(newData string) {
	rwMutex.Lock() // დაწერისთვის დაბლოკეთ
	data = newData
	fmt.Printf("მონაცემების დაწერა: %s\n", data)
	rwMutex.Unlock() // გათავისუფლეთ დაწერისთვის
}

func main() {
	go writeData("Hello")
	time.Sleep(100 * time.Millisecond) // დაელოდეთ დაწერას

	for i := 0; i < 5; i++ {
		go readData() // მრავალჯერადი ერთდროული წაკითხვა ნებადართულია
	}

	time.Sleep(time.Second) // დაელოდეთ გორუტინების დასრულებას
	go writeData("World")
	time.Sleep(100 * time.Millisecond)
	go readData()

	time.Sleep(time.Second)
}