goroutineで順序を考慮する
🧑🏻‍💻

goroutineで順序を考慮する

Category
Author
Tags
Description
Golang初心者なので備忘録も兼ねて
Published
November 9, 2022
Last Updated
Last Updated November 9, 2022
Writings
この記事は約4分で読めます

💡この記事でわかること・解決すること

Golang初心者なので備忘録も兼ねてgoroutineで順序を考慮する場合にどうするかを書いています。結論を言うと先に順序を考慮した配列を作成してその配列を操作すれば良いです。

🤔順番考慮しないコード

当然といえば当然ですが、goroutineはマルチスレッド実行なので実行中にオブジェクトを作ると順番がバラバラになります。まだ数が少ないのでマシですが、Nの数が増えると当然ですが、スレッドも増えるのでもっとバラバラになります。
並列か並行かはこちらの記事を参照するとわかりやすいです。
array := make([]int, 0) for i := 0; i < 10; i++ { array = append(array, i) } log.Print(array) // [0 1 2 3 4 5 6 7 8 9] newArray := make([]int, 0) eg := errgroup.Group{} for _, i := range array { i := i eg.Go(func() error { newArray = append(newArray, i * 2) return nil }) } if err := eg.Wait(); err != nil { log.Fatal(err) } log.Print(newArray) // [18 0 2 4 6 8 10 12 14 16]
💡
こちらでコメントされましたが、上のコードはスレッドセーフではなく共有リソースをマルチスレッドでアクセスしてるので、 sync.Mutex でLock~Unlockをしたほうが良いです🙏 参考

✌️考慮したコード

arrayの配列のindexを使えば順序を維持したまま更新できます。goroutineの中で配列を作成しようとするとバラバラになるので既に作成されている配列なりオブジェクト配列を操作したほうが良いかと思います。
このコードはarrayをそのまま更新していますが、実際にはAモデルからBモデルを作成するなんてときにAモデルをもとにBモデルの配列を作成しておくイメージになります。
array := make([]int, 0) for i := 0; i < 10; i++ { array = append(array, i) } log.Print(array) // [0 1 2 3 4 5 6 7 8 9] eg := errgroup.Group{} for idx, i := range array { i := i idx := idx eg.Go(func() error { array[idx] = i * 2 return nil }) } if err := eg.Wait(); err != nil { log.Fatal(err) } log.Print(array) // [0 2 4 6 8 10 12 14 16 18]

🏌️‍♂️おわりに

どちらかというとプログラミングの基礎的な内容だけど。。。
golang何も考えなくてもすらすら書けるようになりたい。。。

📚中級者向けな良書たち

Web Applicationを学びたい人向け

並行処理を学びたい人向け

 

参考サイト