Keselamatan serentak fungsi Go bermakna fungsi itu masih boleh beroperasi dengan betul apabila dipanggil serentak, mengelakkan kerosakan yang disebabkan oleh berbilang goroutin mengakses data pada masa yang sama. Fungsi selamat selaras boleh menggunakan kaedah seperti kunci, saluran atau pembolehubah atom. Kunci membolehkan goroutine mempunyai akses eksklusif ke bahagian kritikal, saluran menyediakan mekanisme komunikasi yang selamat, dan pembolehubah atom menyediakan akses selamat serentak kepada pembolehubah tertentu. Dalam kes sebenar, saluran digunakan untuk melaksanakan fungsi keselamatan serentak untuk memastikan bahawa berbilang gorout mengakses sumber kongsi dalam susunan yang betul.
Dalam Go, keselamatan concurrency merujuk kepada memastikan fungsi masih boleh beroperasi dengan betul apabila dipanggil serentak. Dalam erti kata lain, fungsi mesti memastikan bahawa keadaan dalamannya tidak rosak oleh akses serentak daripada berbilang goroutine.
Berikut ialah contoh fungsi concurrency-unsafe:
var counter int func IncrementCounter() { counter++ }
Walaupun counter
diisytiharkan sebagai integer atom
, fungsi masih tidak selamat, Kerana tiada mekanisme penyegerakan untuk melindungi akses kepada kaunter
. Ini bermakna berbilang goroutin mungkin cuba menambah counter
pada masa yang sama, menyebabkan perlumbaan data. counter
声明为 atomic
整数,该函数仍然不安全,因为没有同步机制来保护对 counter
的访问。这意味着多个 goroutine 可能同时尝试增加 counter
,导致数据竞争。
要创建并发安全的函数,可以使用几种不同的方法。
1. 使用锁
锁是一种同步机制,它允许 goroutine 在进入临界区(访问共享资源的代码段)之前获取锁。一旦 goroutine 获取锁,它可以独占地访问临界区。例如:
var mu sync.Mutex func IncrementCounter() { mu.Lock() defer mu.Unlock() counter++ }
2. 使用通道
通道是一种用于在 goroutine 之间安全通信的机制。可以使用通道传递消息或同步 goroutine 的执行。例如:
var incrementChan = make(chan struct{}) func IncrementCounter() { incrementChan <- struct{}{} <-incrementChan counter++ }
3. 使用原子变量
原子变量是一种特殊类型的变量,提供对变量的并发安全访问。Go 语言提供了几种内置的原子变量,例如:
import "sync/atomic" var counter int64 func IncrementCounter() { atomic.AddInt64(&counter, 1) }
以下是一个使用通道实现并发安全函数的实战案例:
package main import ( "fmt" "sync" ) var wg sync.WaitGroup func main() { ch := make(chan struct{}) for i := 0; i < 100; i++ { wg.Add(1) go func() { defer wg.Done() <-ch fmt.Println("Goroutine:", i) }() } close(ch) wg.Wait() }
此程序创建了 100 个 goroutine,每个 goroutine 都从通道 ch
ch
. Apabila saluran ditutup, semua gorout akan terjaga dan ID mereka dicetak dalam susunan yang betul. 🎜🎜Dengan menggunakan saluran, kami boleh memastikan bahawa goroutine tidak mengakses sumber yang dikongsi (iaitu saluran) pada masa yang sama, sekali gus mencapai keselamatan serentak. 🎜Atas ialah kandungan terperinci Keselarasan keselamatan fungsi golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!