John Soer
John Soer

Reputation: 551

Threading only block the first thread (Attempt Two)

I have asked this question before - but I have spent some time thinking about it and have implemented a working version.

Overview
1) Threads are being created to perform a certain task.
2) Only one thread can perform the task at a time.
3) Each thread performs the exact same task. (Does a bunch of checks and validations on a system)
3) The threads are being created faster than the task can be performed. (I have no control over the thread creation)

Result is that overtime I get a backlog of threads to perform the task.

What I have implemented goes as follows
1) Thread checks to see how many active threads there are.
2) If there are 0 threads it is marked to PerformTask and it starts the task
3) If there is 1 thread it is marked to PerformTak and it blocks
4) If there is more than 1 thread the thread is not marked to PerformTasks and just dies

The idea is that if there is a thread waiting to perform the task already I just kill the thread.

Here is the code that I came up with

              bool tvPerformTask = false;

              ivNumberOfProcessesSemaphore.WaitOne();
              if (ivNumberOfProcessesWaiting == 0 ||
                  ivNumberOfProcessesWaiting == 1)
              {
                ivNumberOfProcessesWaiting++;
                tvPerformTask = true;
              }
              ivNumberOfProcessesSemaphore.Release();

              if (tvPerformTask)
              {
                //Here we perform the work
                ivProcessSemaphore.WaitOne();
                //Thread save

                ivProcessSemaphore.Release();


                ivNumberOfProcessesSemaphore.WaitOne();
                ivNumberOfProcessesWaiting--;
                ivNumberOfProcessesSemaphore.Release();
              }
              else
              {
                //we just let the thread die
              }

The problem that I have is not that it doesn't work it is just that I do not find the code elegant specifically I am not very happy that I need 2 semaphores an integer and a local flag to control it all. If there a way to implement this or pattern that would make the code simpler.

Upvotes: 3

Views: 143

Answers (2)

ChaosPandion
ChaosPandion

Reputation: 78282

How about this?

private readonly _lock = new object();
private readonly _semaphore = new Semaphore(2, 2);

private void DoWork()
{
    if (_semaphore.WaitOne(0))
    {
        try
        {
            lock (_lock)
            {
                // ...
            }
        }
        finally
        {
            _semaphore.Release();
        }
    }
}

Upvotes: 1

Donnie
Donnie

Reputation: 46933

Consider using a ThreadPool instead of trying to managing the creation and destruction of individual threads on your own.

Upvotes: 0

Related Questions