Nella mia attuale applicazione C#/NET 3.5, ho una coda di task (thread safe) e ho 5 thread di lavoro che devono cercare costantemente le attività in coda. Se un'attività è disponibile, qualsiasi lavoratore annulla l'operazione e intraprende l'azione richiesta.Qual è il metodo più efficiente della CPU per rendere i thread di lavoro in attesa di attività?
mio lavoratore classe thread è il seguente:
public class WorkerThread
{
//ConcurrentQueue is my implementation of thread safe queue
//Essentially just a wrapper around Queue<T> with synchronization locks
readonly ConcurrentQueue<CheckPrimeTask> mQ;
readonly Thread mWorker;
bool mStop;
public WorkerThread (ConcurrentQueue<CheckPrimeTask> aQ) {
mQ = aQ;
mWorker = new Thread (Work) {IsBackground = true};
mStop = false;
}
private void Work() {
while (!mStop) {
if (mQ.Count == 0) {
Thread.Sleep (0);
continue;
}
var task = mQ.Dequeue();
//Someone else might have been lucky in stealing
//the task by the time we dequeued it!!
if (task == null)
continue;
task.IsPrime = IsPrime (task.Number);
task.ExecutedBy = Thread.CurrentThread.ManagedThreadId;
//Ask the threadpool to execute the task callback to
//notify completion
ThreadPool.QueueUserWorkItem (task.CallBack, task);
}
}
private bool IsPrime (int number) {
int limit = Convert.ToInt32 (Math.Sqrt (number));
for (int i = 2; i <= limit; i++) {
if (number % i == 0)
return false;
}
return true;
}
public void Start() {
mStop = false;
mWorker.Start();
}
public void Stop() {
mStop = true;
}
}
problema è che se la coda è vuota, consuma troppa CPU (quasi il 98%). Ho provato AutoResetEvent per notificare ai lavoratori che la coda è stata cambiata. Quindi aspettano effettivamente che quel segnale si imposti. Ha ridotto la CPU a quasi lo 0%, ma non sono del tutto sicuro che questo sia il metodo migliore. Puoi suggerire un metodo migliore per mantenere i thread inattivi senza danneggiare l'utilizzo della CPU?
utilizzando un evento di reset sta per essere l'approccio migliore. –
Un'altra possibilità è utilizzare ThreadPool.QueueUserWorkItem –
Un'altra ancora è utilizzare un timer per controllare la coda e attivare i thread di lavoro. –