2017-08-11 4 views
0

セマフォは、一度にクリティカル領域に入ることができるスレッドの数をカウント数で指定することを意味します。アプリケーション内のスレッド数はいくつですか?どのようにセマフォのカウントを設定するには?

回数を設定し、次のコードは、私たちはいつでも実行されている5つのスレッドを持つことができ、それぞれの時間を意味5.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 

namespace ConsoleApp1 
{ 
    class Program 
    { 
     static Semaphore semaphore = new Semaphore(5, 5); 
     static void Main(string[] args) 
     { 
      Task.Factory.StartNew(() => 
      { 
       for (int i = 1; i <= 15; ++i) 
       { 
        PrintSomething(i); 
        if (i % 5 == 0) 
        { 
         Thread.Sleep(2000); 
        } 
       } 
      }); 
      Console.ReadLine(); 
     } 

     public static void PrintSomething(int number) 
     { 
      semaphore.WaitOne(); 
      Console.WriteLine(number); 
      semaphore.Release(); 
     } 
    } 
} 

です。印刷結果がポイントを確認します。

私の質問は、あまりにも多くのスレッドが実行されて表示されないことです。 15スレッドが稼働していると言えば、たびに5スレッドだけを共存させることができます。スレッドは2つしかありません。 thread

私は何か誤解していますか?

+0

タイトルを意味のあるものに編集してください。 * Semaphore *と* Multithreading *はどちらもタグに入っているので、重複してタイトルには含まれていないので意味のない内容にはなりません。あなたのタイトルは、あなたが持っている問題やあなたが質問している質問を、将来の読者が検索結果のリストに表示するのに役立つ方法で説明する必要があります。 –

+1

専用のスレッドではなく、スレッドプール上で作業をスケジューリングする可能性があります。 – vcsjones

+0

システムはあなたに最初のスレッドを与えます。タスクを実行するワーカースレッドを作成しました。それは2つを作る。 –

答えて

0

Task.Factory.StartNew()を使用して1つの追加スレッドを開始すると、それだけです。そのスレッドでは、PrintSomething()メソッドを順番に呼び出すので、スレッド出力のスクリーンショットが正しいです。次のように

はあなたのコードを変更し

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 

namespace SempahoreTest1 
{ 
    class Program 
    { 
    static Semaphore semaphore = new Semaphore(5, 5); 

    static void Main(string[] args) 
    { 
     for (int i = 1; i <= 15; ++i) 
     { 
     Task.Factory.StartNew((state) => 
     { 
      int number = (int)state; 

      PrintSomething(number); 
      if (i % 5 == 0) 
      { 
      Thread.Sleep(2000); 
      } 
     }, i); 
     } 
     Console.ReadLine(); 
    } 

    public static void PrintSomething(int number) 
    { 
     semaphore.WaitOne(); 
     try 
     { 
     Console.WriteLine("Thread: {0}, Number: {1}", Thread.CurrentThread.ManagedThreadId, number); 
     } 
     finally 
     { 
     semaphore.Release(); 
     } 
    } 
    } 
} 

を更新:

良く説明、どのようにセマフォの作品は、次のようになります。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 

namespace SempahoreTest1 
{ 
    class Program 
    { 
    static Semaphore semaphore = new Semaphore(5, 5); 
    static Random random = new Random(); 

    static void Main(string[] args) 
    { 
     Parallel.For(1, 16, PrintSomething); 

     Console.ReadLine(); 
    } 

    public static void PrintSomething(int number) 
    { 
     semaphore.WaitOne(); 
     try 
     { 
     Console.WriteLine("Thread: {0}, Number: {1}, Access granted", Thread.CurrentThread.ManagedThreadId, number); 
     // sleep to simulate long running method 
     Thread.Sleep(random.Next(1000, 5000)); 
     } 
     finally 
     { 
     semaphore.Release(); 
     Console.WriteLine("Thread: {0}, Number: {1}, Semaphore released", Thread.CurrentThread.ManagedThreadId, number); 
     } 
    } 
    } 
} 

並列ループがPrintSomething()からを呼び出します異なるスレッド。すべての呼び出しで、セマフォカウンタは0に達するまで減少します。PrintSomething()の次の呼び出しは、最初の呼び出しがsemaphore.Release()になるまで、semaphore.WaitOne()にブロックされ、セマフォカウンタを再びインクリメントします。そうでなくても... 最初の5回のコールは非常に高速です。なぜなら、最大のセマフォカウント(5)が利用可能であるからです。次に、異なるスリープ時間のために、メソッドコール出力は、セマフォーがどのように動作するかを示します。

+0

はい。 [リンク](http://dotnetpattern.com/multi-threading-interview-questions)の例を使って概念を間違って説明していますか?そしてリンクでは、印刷結果は毎回5を出力します。私は5つ以上の糸があると思ったので混乱しています。 – Bigeyes

+0

@Bigeyes:この例は完全に間違っています。 semaphore.WaitOne()とsemaphore.Release()、同じ出力をコメントアウトすることができます。これは、同じスレッドからのループ内の順次呼び出しのためです。それは5回増分し、その後2秒間待つ。 – KBO

関連する問題