Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ThreadQueue problems in "Accelerated C# 2008"

Example for threading queue book "Accelerated C# 2008" (CrudeThreadPool class) not work correctly. If I insert long job in WorkFunction() on 2-processor machine executing for next task don't run before first is over. How to solve this problem? I want to load the processor to 100 percent

public class CrudeThreadPool
{
    static readonly int MAX_WORK_THREADS = 4;
    static readonly int WAIT_TIMEOUT = 2000;
    public delegate void WorkDelegate();

    public CrudeThreadPool()
    {
        stop = 0;
        workLock = new Object();
        workQueue = new Queue();
        threads = new Thread[MAX_WORK_THREADS];
        for (int i = 0; i < MAX_WORK_THREADS; ++i)
        {
            threads[i] = new Thread(new ThreadStart(this.ThreadFunc));
            threads[i].Start();
        }

    }


    private void ThreadFunc()
    {
        lock (workLock)
        {
            int shouldStop = 0;
            do
            {
                shouldStop = Interlocked.Exchange(ref stop, stop);
                if (shouldStop == 0)
                {
                    WorkDelegate workItem = null;

                    if (Monitor.Wait(workLock, WAIT_TIMEOUT))
                    {
                        // Process the item on the front of the queue
                        lock (workQueue)
                        {
                            workItem = (WorkDelegate)workQueue.Dequeue();
                        }
                        workItem();
                    }
                }
            } while (shouldStop == 0);
        }
    }

    public void SubmitWorkItem(WorkDelegate item)
    {
        lock (workLock)
        {

            lock (workQueue)
            {
                workQueue.Enqueue(item);
            }
            Monitor.Pulse(workLock);
        }
    }

    public void Shutdown()
    {
        Interlocked.Exchange(ref stop, 1);
    }
    private Queue workQueue;
    private Object workLock;
    private Thread[] threads;
    private int stop;
}

public class EntryPoint
{
    static void WorkFunction()
    {
        Console.WriteLine("WorkFunction() called on Thread 0}", Thread.CurrentThread.GetHashCode());
        //some long job
        double s = 0;
        for (int i = 0; i < 100000000; i++)
            s += Math.Sin(i);
    }

    static void Main()
    {
        CrudeThreadPool pool = new CrudeThreadPool();
        for (int i = 0; i < 10; ++i)
        {
            pool.SubmitWorkItem(
            new CrudeThreadPool.WorkDelegate(EntryPoint.WorkFunction));
        }
        pool.Shutdown();
    }
}
like image 288
Singlet Avatar asked Feb 27 '26 16:02

Singlet


1 Answers

I can see 2 problems:

  • Inside ThreadFunc() you take a lock(workLock) for the duration of the method, meaning your threadpool is no longer async.

  • in the Main() method, you close down the threadpool w/o waiting for it to finish. Oddly enough that is why it is working now, stopping each ThreadFunc after 1 loop.

like image 53
Henk Holterman Avatar answered Mar 01 '26 07:03

Henk Holterman