プログラムを書こう!

実務や自作アプリ開発で習得した役に立つソフトウェア技術情報を発信するブログ

C#でSemaphoreを使用する

この記事は2022年06月04日に投稿しました。

目次

  1. はじめに
  2. C#でSemaphoreを使用する
  3. おわりに

1. はじめに

こんにちは、iOSのエディタアプリPWEditorの開発者の二俣です。
今回は業務で使用しているC#でSemaphoreを使用する方法についてです。

目次へ

2. C#でSemaphoreを使用する

C#でSemaphoreを使用するには、以下のような実装にします。

実装例

※MicrosoftのAPI Referenceのサンプルを参考にしました。

using System;
using System.Threading;

namespace SampleSemaphore
{
    internal class Program
    {
        /// <summary>
        /// セマフォ
        /// </summary>
        private static Semaphore _pool;

        /// <summary>
        /// ワーカースレッドのウェイト時間のパディング
        /// </summary>
        private static int _padding;

        static void Main(string[] args)
        {
            // 同時に許可されるセマフォ要求の初期値0、最大数3でセマフォを生成します。
            _pool = new Semaphore(0, 3);

            // スレッドを5つ生成し、開始します。
            for (var i = 0; i < 5; ++i)
            {
                var thread = new Thread(new ParameterizedThreadStart(Worker));
                thread.Start(i);
            }

            // ウェイトします。
            Thread.Sleep(500);

            Console.WriteLine("セマフォから3つ出します。");
            _pool.Release(3);

            Console.WriteLine("メインスレッドを終了します。");

            Console.ReadKey();
        }

        /// <summary>
        /// ワーカースレッド処理
        /// </summary>
        /// <param name="num"スレッド番号</param>
        private static void Worker(object num)
        {
            Console.WriteLine($"スレッド{num}を開始し、セマフォのシグナルを待ちます。");
            _pool.WaitOne();

            // パディング値を加算します。
            int padding = Interlocked.Add(ref _padding, 100);

            Console.WriteLine($"スレッド{num}がセマフォに入ります。");

            // 1秒+パディング値分ウェイトします。
            Thread.Sleep(1000 + padding);

            Console.WriteLine($"スレッド{num}がセマフォから出ます。");
            Console.WriteLine($"スレッド{num}の前のセマフォカウントは{_pool.Release()}です。");
        }
    }
}

実行結果

スレッド0を開始し、セマフォのシグナルを待ちます。
スレッド1を開始し、セマフォのシグナルを待ちます。
スレッド4を開始し、セマフォのシグナルを待ちます。
スレッド2を開始し、セマフォのシグナルを待ちます。
スレッド3を開始し、セマフォのシグナルを待ちます。
セマフォから3つ出ます。
メインスレッドを終了します。
スレッド1がセマフォに入ります。
スレッド0がセマフォに入ります。
スレッド4がセマフォに入ります。
スレッド1がセマフォから出ます。
スレッド1の前のセマフォカウントは0です。
スレッド2がセマフォに入ります。
スレッド4がセマフォから出ます。
スレッド4の前のセマフォカウントは0です。
スレッド3がセマフォに入ります。
スレッド0がセマフォから出ます。
スレッド0の前のセマフォカウントは0です。
スレッド2がセマフォから出ます。
スレッド2の前のセマフォカウントは1です。
スレッド3がセマフォから出ます。
スレッド3の前のセマフォカウントは2です。

API Reference

Semaphoreクラス

目次へ

3. おわりに

以前C++/CLIで

www.paveway.info

を紹介しました。
今回C#で排他制御を行う必要があり、MicrosoftのAPI Referenceのサンプルを参考にしました。

紹介している一部の記事のコードはGitlabで公開しています。
興味のある方は覗いてみてください。

目次へ


私が勤務しているニューラルでは、主に組み込み系ソフトの開発を行っております。
弊社製品のハイブリッドOS Bi-OSは高い技術力を評価されており、特に制御系や通信系を得意としています。
私自身はiOSモバイルアプリウィンドウズアプリを得意としております。
ソフトウェア開発に関して相談などございましたら、お気軽にご連絡ください。

また一緒に働きたい技術者の方も随時募集中です。
興味がありましたらご連絡ください。

EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688

目次へ