golangを開く:WaitGroup Mutex

CSPは、Communicating SequentialProcessの略語です。中国語はCommunicationSequential Processと呼ぶことができます。これは並行プログラミングモデルです。元々はTonyHoareの1977年の論文で説明され、多くのプログラミング言語の設計に影響を与えました。

golangCSPモデル

golang言語は、CSPモデルのすべての理論を完全に実装しているわけではなく、プロセスとチャネルの2つの概念を借用しているだけです。golang言語でのプロセスのパフォーマンスは、実際に同時に実行されるエンティティであるgoroutineです。各エンティティは、チャネルを介して通信し、データ共有を実現します。
最も古典的なデータ通信共有理論

通信によるメモリの共有

Do not communicate by sharing memory; instead, share memory by communicating

共有メモリを介して通信しないでください。逆に、通信を介してメモリを共有してください。
これは、golangが高い同時実行性を実現するための基本的な通信理論です。
golang言語では、複数のgoroutine間のデータ通信はチャネルを介して実現されます。

sync.WaitGroupの使用

複数のゴルーチンを実行する必要がある場合は、time.sleepを使用し、数秒遅らせて、各ゴルーチンを実行できるようにします。

func testPrint(i int) {
	fmt.Println(i)
}
func main() {
	for i:=0;i<5;i++ {
		go testPrint(i)
	}
	time.Sleep(time.Second)
}

ただし、本番プロジェクトでこれを書き込むことはできません。1Sの遅延により、すべてのゴルーチンが完了せずに実行される可能性があり、1000Sの遅延が1ミリ秒で実行される可能性があり、他の999Sが待機しているため、実行時間が長くなります。プログラム。
したがって、sync.WaitGroupがあります

func testPrint(wg *sync.WaitGroup, i int) {
	fmt.Println(i)
	wg.Done()
}
func main() {
	var wg = new(sync.WaitGroup)
	for i:=0;i<5;i++ {
		wg.Add(1)
		go testPrint(wg,i)
	}
	wg.Wait()
}

WaitGroupは理解しやすいです。実際、これは内部カウンターです。ゴルーチン動作を実行する前に、wg.Add(1)を実行し、カウンターに+1を指定します。実行後、wg.Done()を実行します。これは、ゴルーチンの実行が完了し、カウンターが-1です。、Wg.Wait()はコードの実行をブロックし、WaitGroupに追加されたすべてのゴルーチンが実行されるのを待ち(カウンターは0になります)、その後プログラムを終了します。
これは、すべてのゴルーチンが実行されるのを待つ必要性を完全に解決します。

sync.Mutex

sync.Mutex、ミューテックスの排他ロック。
各ゴルーチンが変数を正常に変更できるように、変数を維持する必要があります。ミューテックスがない場合は、次のコードである可能性があります。

func testPrint(wg *sync.WaitGroup, i int) {
	count++
	fmt.Println(i)
	wg.Done()
}
var count int
func main() {
	count = 0
	var wg = new(sync.WaitGroup)
	for i:=0;i<500;i++ {
		wg.Add(1)
		go testPrint(wg,i)
	}
	wg.Wait()
	fmt.Printf("count:%d",count)
}

特定の値500であると予想されます。実際、500ではないことがよくあります。これは、複数のゴルーチンが同時にカウント値を変更し、ミューテックスロックで試してみるためです。

func testPrint(wg *sync.WaitGroup, i int) {
	defer func() {
		mu.Unlock()
	}()
	mu.Lock()
	count++
	fmt.Println(i)
	wg.Done()
}
var count int
var mu *sync.Mutex
func main() {
	count = 0
	mu = new(sync.Mutex)
	var wg = new(sync.WaitGroup)
	for i:=0;i<500;i++ {
		wg.Add(1)
		go testPrint(wg,i)
	}
	wg.Wait()
	fmt.Printf("count:%d",count)
}

結果は500の固定値であり、予想と一致していました。

おすすめ

転載: blog.csdn.net/feifeixiang2835/article/details/108589395