Golang is a language that supports concurrent programming, but in concurrent programming, data inconsistency is prone to occur. Therefore, in Golang, we need to use synchronization methods to ensure the correctness and reliability of the program. This article will introduce the synchronization method in Golang.
1. Mutex lock
Mutex lock is the most commonly used synchronization mechanism. Shared resources can be locked through mutex locks to ensure that only one thread can access the resource at the same time. Sharing resources avoids the occurrence of race conditions. In Golang, mutex locks are implemented through sync.Mutex in the standard library. The following is a sample code for a mutex lock:
package main import ( "fmt" "sync" "time" ) func main() { var lock sync.Mutex var wg sync.WaitGroup var count int for i := 0; i < 10; i++ { wg.Add(1) go func() { lock.Lock() // 加锁 defer lock.Unlock() // 解锁 count++ time.Sleep(time.Second) fmt.Println(count) wg.Done() }() } wg.Wait() }
2. Read-write lock
The read-write lock is a special mutex lock that allows multiple threads to access shared resources at the same time. Read operations, but during write operations, only one thread can access the shared resource at the same time. In Golang, read-write locks are implemented through sync.RWMutex in the standard library. The following is a sample code for a read-write lock:
package main import ( "fmt" "sync" "time" ) func main() { var lock sync.RWMutex var wg sync.WaitGroup var count int for i := 0; i < 10; i++ { wg.Add(1) go func(idx int) { // 多个线程读操作可以同时进行 lock.RLock() fmt.Printf("读协程%d,count=%d\n", idx, count) lock.RUnlock() // 一个线程写操作时,其它线程无法读写 lock.Lock() count++ fmt.Printf("写协程%d,count=%d\n", idx, count) time.Sleep(time.Second) lock.Unlock() wg.Done() }(i) } wg.Wait() }
3. Condition variable
Condition variable is a synchronization mechanism that allows threads to synchronize based on specific conditions. In Golang, condition variables are implemented through sync.Cond in the standard library. The following is a sample code for a condition variable:
package main import ( "fmt" "sync" "time" ) func main() { var lock sync.Mutex var wg sync.WaitGroup var cond = sync.NewCond(&lock) done := false for i := 0; i < 5; i++ { wg.Add(1) go func(idx int) { lock.Lock() for !done { cond.Wait() // 等待通知 } fmt.Printf("协程%d收到通知\n", idx) lock.Unlock() wg.Done() }(i) } time.Sleep(time.Second) lock.Lock() done = true // 向所有协程发送通知 cond.Broadcast() lock.Unlock() wg.Wait() }
4. Atomic operation
Atomic operation is an operation that can read and write memory data without locking. In Golang, atomic operations are implemented through sync/atomic in the standard library. The following is a sample code for an atomic operation:
package main import ( "fmt" "sync/atomic" ) func main() { var value int32 atomic.StoreInt32(&value, 10) fmt.Println(atomic.LoadInt32(&value)) atomic.AddInt32(&value, 5) fmt.Println(atomic.LoadInt32(&value)) atomic.CompareAndSwapInt32(&value, 15, 20) // 如果value等于15,则将其更新为20 fmt.Println(atomic.LoadInt32(&value)) }
Through synchronization methods such as mutex locks, read-write locks, condition variables, and atomic operations, we can effectively ensure the correctness and reliability of Golang programs.
The above is the detailed content of An article introducing synchronization methods in Golang. For more information, please follow other related articles on the PHP Chinese website!