並行プログラミングでは、ロックは共有リソースを保護するために使用されるメカニズムです。 Go 言語では、ロックは同時実行性を実現するための重要なツールの 1 つです。これにより、複数のコルーチンが共有リソースに同時にアクセスした場合、1 つのコルーチンだけがこれらのリソースを読み取りまたは変更できるようになります。この記事では、読者が並行プログラミングをよりよく理解できるように、Go 言語でのロックの使用法を紹介します。
相互排他ロックは、Go 言語で最も一般的に使用されるロック メカニズムです。これにより、クリティカル セクションに同時にアクセスできるコルーチンは 1 つだけになります。平たく言えば、ミューテックス ロックは、共有リソースをロック クリティカル セクションでラップすることにより、同時に 1 つのコルーチンのみがアクセスできるようにします。
Go 言語でのミューテックス ロックの使用は非常に簡単です。同期パッケージの Mutex タイプを使用して、mutex ロックを作成できます:
import "sync" var mutex = &sync.Mutex{}
その後、共有リソースを保護する必要がある場所で、次のコードを使用してロックを取得できます。 ##
mutex.Lock() defer mutex.Unlock()価値があります ミューテックス ロックは再入をサポートしていないことに注意してください。コルーチンがすでにロックを取得している場合、再度ロックを取得しようとするとデッドロックが発生します。したがって、通常は defer ステートメントを使用して、コルーチンの終了時にロックを自動的に解放します。 次に、ミューテックス ロックの使用例を示します。
import ( "fmt" "sync" ) var count = 0 var mutex = &sync.Mutex{} func increment(wg *sync.WaitGroup) { mutex.Lock() defer mutex.Unlock() count++ wg.Done() } func main() { var wg sync.WaitGroup for i := 0; i < 1000; i++ { wg.Add(1) go increment(&wg) } wg.Wait() fmt.Println("Count:", count) }この例では、ミューテックス ロックを使用してカウンターを保護します。 1000 個のコルーチンがインクリメント関数を同時に実行し、毎回カウンターに 1 を加算します。ミューテックス ロックを使用しているため、プログラムは最終的なカウンター値を正しく出力できます。
import "sync" var rwlock = &sync.RWMutex{}読み取りロックと書き込みロックの取得方法は異なります。一般的な使用法は次のとおりです。
import ( "fmt" "sync" ) var count = 0 var rwlock = &sync.RWMutex{} func increment(wg *sync.WaitGroup) { rwlock.Lock() defer rwlock.Unlock() count++ wg.Done() } func read(wg *sync.WaitGroup) { rwlock.RLock() defer rwlock.RUnlock() fmt.Println("Count:", count) wg.Done() } func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go increment(&wg) } wg.Wait() for i := 0; i < 5; i++ { wg.Add(1) go read(&wg) } wg.Wait() }この例では、カウンタにデータを書き込むために 10 個のコルーチンを開き、カウンタ データを読み取るために 5 個のコルーチンを同時に開きました。読み取り/書き込みロックを使用すると、プログラムは書き込み操作のアトミック性を確保しながら、効率的な方法で共有リソースから読み取ることができます。
import ( "fmt" "sync/atomic" "time" ) var count int32 = 0 func increment(wg *sync.WaitGroup) { defer wg.Done() atomic.AddInt32(&count, 1) } func printCount() { fmt.Println("Count: ", atomic.LoadInt32(&count)) } func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go increment(&wg) } wg.Wait() printCount() time.Sleep(time.Second) for i := 0; i < 3; i++ { wg.Add(1) go increment(&wg) } wg.Wait() printCount() }この例では、atomic.Add 関数を使用してカウンターに対してアトミックな加算操作を実行し、atomic.Load 関数を使用してカウンタに対してアトミックな加算操作を実行します。カウンタ値をアトミックに読み取ります。アトミック操作を使用することで、ロックのオーバーヘッドを回避し、より効率的な同時プログラミングを実現できます。
以上がGo でロックを使用するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。