1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Go言語におけるセマフォの利用:なぜ必要で、容量の決め方

Posted at

はじめに

Go言語における並行プログラミングでは、セマフォは非常に重要な役割を果たします。この記事では、セマフォがなぜ必要なのか、そしてセマフォの容量の決定方法について説明します。

セマフォとは何か

セマフォは、複数のゴルーチンが共有リソースへのアクセスを調整するための同期原理の一つです。Goでは、セマフォはチャネルを使って表現されることが多く、以下のような形で空の構造体のチャネルchan struct{}を使用することが一般的です。

sem := make(chan struct{}, 2)

なぜセマフォが必要なのか

複数のゴルーチンが共有リソースに同時にアクセスしようとすると、データの不整合や競合状態を引き起こす可能性があります。この問題を避けるために、セマフォはリソースへの同時アクセスを制限します。

具体的には、以下のコードではデータベースへの書き込みを調整するためにセマフォが使用されています。

sem <- struct{}{}
defer func() {
  <-sem
}()
_, err = db.Exec("INSERT INTO rates (date, currency, rate) VALUES (?, ?, ?)", time.Now(), result.Currency, result.Rate)

セマフォを利用することで、一度に実行できるデータベースへの書き込みの数を制限し、データベースの過負荷やデータの不整合を防ぐことができます。

セマフォの容量の決定方法

セマフォの容量は、一度に許可されるリソースへのアクセスの最大数を表します。この例では、sem := make(chan struct{}, 2)が容量2のセマフォを作成しています。これは一度に最大2つのデータベース書き込み操作を許可することを示しています。

セマフォの容量を決定するときは、システムの要件とリソースの性能を考慮に入れる必要があります。例えば、データベースへの書き込みが高負荷になりすぎてパフォーマンスが低下する可能性があるため、それを適切に制限する必要があります。一方で、同時アクセスの数が少なすぎると、システムのスループットが低下する可能性があります。

そのため、容量の設定は、システムの性能要件、リソースへのアクセスパターン、およびリソース自体の性能(この場合、データベースの書き込みパフォーマンス)に基づいて調整する必要があります。また、負荷テストやベンチマーキングを行い、システムの応答性とスループットを維持しながらリソースへの最大同時アクセス数を定量化することも有効な手段です。

以下のようなコードでシステムのパフォーマンスをテストすることができます。

for i := 0; i < 100; i++ {
    go func() {
        sem <- struct{}{}
        defer func() {
            <-sem
        }()
        _, err = db.Exec("INSERT INTO rates (date, currency, rate) VALUES (?, ?, ?)", time.Now(), "USD", 1.0)
        if err != nil {
            log.Println(err)
        }
    }()
}

まとめ

Go言語におけるセマフォは、リソースへの同時アクセスを制御する強力なツールです。適切な容量の決定により、システムのパフォーマンスと安定性を最適化することができます。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?