1

I need to do some task in parallel using semaphore. I try this:

Semaphore sema = new Semaphore(2,2); Thread[] Threads = new Thread[5]; for (int k = 0; k < 5; k++) { sema.WaitOne(); Console.WriteLine((k + 1) + " started"); Threads[k] = new Thread(ThreadMethod1); Threads[k].Start(k + 1); sema.Release(); } static void ThreadMethod1(object id) { Thread.Sleep(50); Console.WriteLine(id + " completed"); } 

Output looks like:

1 started 2 started 3 started 4 started 5 started 1 completed 2 completed 4 completed 3 completed 5 completed 

Isn't semaphore supposed to let only 2 threads to run? I don't get it or doing something wrong?

1
  • 4
    Yes, but you are entering exiting the semaphore in the main thread in each cycle, so the semaphore will always be in non-blocking status. Commented Feb 24, 2015 at 9:55

2 Answers 2

9

You are entering/exiting the semaphore in the "main" thread. It's useless, because in each "cycle" you'll both enter and exit it. In this modified example, you enter the semaphore in the main thread and upon finishing the worker thread you exit it.

Note that I had to pass the semaphore to the worker thread (I used a Tuple, but other methods are ok)

static void Main(string[] args) { Semaphore sema = new Semaphore(2, 2); Thread[] Threads = new Thread[5]; for (int k = 0; k < 5; k++) { sema.WaitOne(); Console.WriteLine((k + 1) + " started"); Threads[k] = new Thread(ThreadMethod1); Threads[k].Start(Tuple.Create(k + 1, sema)); } } static void ThreadMethod1(object tuple) { Tuple<int, Semaphore> tuple2 = (Tuple<int, Semaphore>)tuple; Thread.Sleep(50); Console.WriteLine(tuple2.Item1 + " completed"); tuple2.Item2.Release(); } 

You could move the sema.WaitOne "inside" the ThreadMethod1, but it would be different: all the threads would be created but would "wait" and only 2 at a time would do the "real work". As written instead up to two threads are created (and do the work)

Sign up to request clarification or add additional context in comments.

1 Comment

Looks like i tired and can't think properly. Thank you!
0

All you have to do is to move operations on the semaphore from main thread. Small correction to your code will solve it.

public static Semaphore sema = new Semaphore(2, 2); static void Main(string[] args) { Thread[] Threads = new Thread[5]; for (int k = 0; k < 5; k++) { Console.WriteLine((k + 1) + " started"); Threads[k] = new Thread(ThreadMethod1); Threads[k].Start(k + 1); } } static void ThreadMethod1(object id) { sema.WaitOne(); Thread.Sleep(1000); Console.WriteLine(id + " completed"); sema.Release(); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.