同期パッケージは、ミューテックス ロックなどの基本的な同期プリミティブを提供します。 Once 型と WaitGroup 型を除き、他のほとんどの型は、基礎となる関数ライブラリ用に設計されています。より高いレベルの同期は、チャネルと通信を通じてより適切に実現されます。同時アクセスを許可する例の大部分では、問題を解決するためにミューテックスが使用されています。ただし、チャネルを使用して同期メカニズムを提供する方法を示す例はほとんどありません。そこで、この記事でそれについて説明しましょう。
バッファ チャネルに書き込む必要がある名前の列があると仮定します。ファイルには、それぞれの名前が連続して 1000 回書き込む必要があり、異なる名前間の重複は許可されません。
package main import ( "errors" "fmt" "os" "sync" ) func main() { file, err := os.Create("record.txt") defer func() { if err := recover(); err != nil { fmt.Printf("Error encounter: %w", err) } file.Close() }() if err != nil { panic(errors.New("Cannot create/open file")) } ss := []string{ //string slice literals "James", "Avery", "Peter", "John", "Beau", } chanLock := make(chan int, 1) //1 var wg sync.WaitGroup for _, str := range ss { //2 wg.Add(1) //amended thanks to response from Wang //Sheng go func(aString string) { chanLock <- 1 //3 for i := 0; i < 1000; i++ { file.WriteString(aString + "\n") } <-chanLock //4 wg.Done() //5 }(str) //pass by value } wg.Wait() }
上記のコードでは、 //1 バッファー 1 を持つチャネルを作成しました。 //2 名前の数と同じ数のゴルーチンを作成しました。 //3 はロックに相当し、 //4 はロック解除に相当します。そのため、複数のゴルーチンが同期的に Record.txt ファイルに名前を書き込むことができますが、ファイルを操作できるのは一度に 1 つのゴルーチンだけです。
サブゴルーチンがタスクを完了する前にメイン コルーチンが終了しないようにするために WaitGroup を使用していることに注意してください。
この記事がお役に立てば幸いです。コーディングをお楽しみください!
以上が学んだ!バッファリングされたチャネルをミューテックスとして使用するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。