Task Scheduler Using Priority MultiThreading

I am going to run a C # .NET 4.0 project that creates a task scheduler.

  • The task has no set date and potentially works for a long time, up to several days.
  • The task has 3 priorities: simple, normal, critical; from lowest to highest.
  • A new task is constantly being created.
  • A newer job with a higher priority should take precedence over a lower priority, even if the old job has been created for a long time.
  • Each task will be processed in one long thread.
  • The task is repeated. The task status is saved in the database, so you can pause the task or stop the task at any time.

My plan is to use a semaphore and set the number of concurrent entries to the number of system cores. A new thread will be created for each job in the queue, and all threads will be blocked by the semaphore at the beginning.

My problem is to ensure that the high priority thread enters the semaphore first when the semaphore calls the release () method. Doable?

My second problem is that the thread that is inside the semaphore should exit when a thread of jobs with a higher priority comes into existence, and the thread of returning jobs returns to the thread queue to wait for the semaphore. Doable?

Is semaphore the right approach for these two problems? If not, what do you suggest?

+3
source share
3

, - ...

:

for(int i=0; i < Environment.ProcessorCount; i++)
{
    Thread t = new Thread(RunWork);
    // setup thread
    t.Start();
    threads.Add(t);
}

interface ITask {
    PrioirtyType Prioirty { get; }
    bool Complete { get; }
    void PerformOneUnitOfWork();
}

. , , , ..

class MyQueue<TJob> where TJob : ITask 
{
    Queue<TJob> high, med, low;
    bool GetNextJob(ref TJob work)
    {
        if(work.Priority == PriorityType.High && !work.Complete)
            return true;
        lock(this)
        {
            if(high.Count > 0)
            {
                Enqueue(work);//requeue to pick back up later
                work = high.Dequeue();
                return true;
            }
            if(work.Priority == PriorityType.Med && !work.Complete)
                return true;
            if(med.Count > 0)
            {
                Enqueue(work);//requeue to pick back up later
                work = med.Dequeue();
                return true;
            }
            if(!work.Complete)
                return true;
            if(low.Count > 0)
            {
                work = low.Dequeue();
                return true;
            }
            work = null;
            return false;
        }

    void Enqueue(TJob work)
    {
        if(work.Complete) return;
        lock(this)
        {
            else if(work.Priority == PriorityType.High) high.Enqueue(work);
            else if(work.Priority == PriorityType.Med) med.Enqueue(work);
            else low.Enqueue(work);
        }
    }
}

:

public void RunWork()
{
    ITask job;
    while(!_shutdown.WaitOne(0))
    {
        if(queue.GetNextJob(ref job))
            job.PerformOneUnitOfWork();
        else
            WaitHandle.WaitAny(new WaitHandle[] { _shutdown, queue.WorkReadyHandle });
    }
}
+4

? , ?

. , ( ) , - , . , , WCF- , .

. ThreadPool .

, , , . .

, , , . , ( Interlocked.Increment/Decrement) ManualResetEvent .

+3

There is a great infrastructure ported from Java to C #.

http://quartznet.sourceforge.net/

-1
source

Source: https://habr.com/ru/post/1790518/


All Articles