乐闻世界logo
搜索文章和话题

在 Golang 中如何处理对共享资源的并发访问?

1个答案

1

Handling concurrent access to shared resources in Golang primarily involves several methods, with mutexes and channels being the most commonly used. I will provide detailed explanations of these two methods along with corresponding code examples.

1. Using Mutex

A mutex is a synchronization primitive designed to prevent conflicts among multiple goroutines when accessing shared resources. Using sync.Mutex to protect shared resources ensures that only one goroutine can access it at a time.

Example:

go
package main import ( "fmt" "sync" ) var ( counter int lock sync.Mutex ) func increment() { lock.Lock() // Lock before accessing shared resource defer lock.Unlock() // Ensure lock is released using defer counter++ // Safely modify shared resource } func main() { var wg sync.WaitGroup // Create multiple goroutines to simulate concurrent access for i := 0; i < 100; i++ { wg.Add(1) go func() { defer wg.Done() increment() }() } wg.Wait() // Wait for all goroutines to complete fmt.Println("Counter:", counter) }

In this example, the mutex ensures thread-safe access to counter. Regardless of how many goroutines are launched, the output will consistently be 100.

2. Using Channels

Channels are a fundamental feature in Go, enabling safe data transfer between goroutines. They can also be used to synchronize access to shared resources by controlling data flow.

Example:

go
package main import ( "fmt" "sync" ) func worker(jobs <-chan int, results chan<- int) { for job := range jobs { results <- job * 2 // Process job and send result to results channel } } func main() { jobs := make(chan int, 100) results := make(chan int, 100) var wg sync.WaitGroup // Start workers to process tasks for w := 0; w < 3; w++ { wg.Add(1) go func() { defer wg.Done() worker(jobs, results) }() } // Send tasks to jobs channel for j := 1; j <= 5; j++ { jobs <- j } close(jobs) wg.Wait() // Wait for all workers to complete close(results) // Close results channel // Collect all results for result := range results { fmt.Println(result) } }

In this example, we establish a jobs channel and a results channel. Worker goroutines receive tasks from the jobs channel and send processed results to the results channel, thereby ensuring safe access to shared resources and data synchronization.

Summary

In Go, concurrent access to shared resources is commonly managed using two mechanisms: mutexes and channels. The selection of which to use depends on the specific context. Mutexes are ideal for safeguarding simple shared data, whereas channels excel in communication and synchronization between goroutines.

2024年10月26日 16:52 回复

你的答案