Следующий код 5 потоков с разными приоритетами конкурируют за доступ к процессору с 8 ядрами (Mac OS X 10.8.5, Mono). Каждый поток увеличивает счетчик.Врезка с наименьшим приоритетом вызывается больше раз
using System;
using System.Threading;
class PriorityTesting
{
static long[] counts;
static bool finish;
static void ThreadFunc(object iThread)
{
while(true)
{
if(finish)
break;
counts[(int)iThread]++;
}
}
static void Main()
{
counts = new long[5];
Thread[] t = new Thread[5];
for(int i=0; i<t.Length; i++)
{
t[i] = new Thread(ThreadFunc);
t[i].Priority = (ThreadPriority)i;
}
// Запускаем потоки
for(int i=0; i<t.Length; i++)
t[i].Start(i);
// Даём потокам возможность поработать 10 c
Thread.Sleep(10000);
// Сигнал о завершении
finish = true;
// Ожидаем завершения всех потоков
for(int i=0; i<t.Length; i++)
t[i].Join();
// Вывод результатов
for(int i=0; i<t.Length; i++)
Console.WriteLine("Thread with priority {0, 15}, Counts: {1}", (ThreadPriority)i, counts[i]);
}
}
Компиляция:
$ mcs PriorityTesting.cs
$ mono PriorityTesting.exe
Выходные:
Thread with priority Lowest, Counts: 178544880
Thread with priority BelowNormal, Counts: 167783608
Thread with priority Normal, Counts: 160593225
Thread with priority AboveNormal, Counts: 79123315
Thread with priority Highest, Counts: 81623159
Как это что нить с самым низким приоритетом вызывается больше раз, чем нитей с наивысшим приоритетом?
UPD:
Тот же самый код на процессоре с 2 ядрами дает (Windows, .NET):
Thread with priority Lowest, Counts: 7608195
Thread with priority BelowNormal, Counts: 10457706
Thread with priority Normal, Counts: 17852629
Thread with priority AboveNormal, Counts: 297729812
Thread with priority Highest, Counts: 302506232
Почему разница?
Вы заметили другое поведение, если вы исправили код, чтобы переменная 'finish' была отмечена' volatile' (как и должно быть)? Конечно, я хватаюсь за соломинку, но это _might_ имеет значение, в зависимости от того, на каком оборудовании вы работаете. –
Я бы как-то изменил «ThreadFunc», чтобы дать больше шансов переключить потоки, такие как Thread.Yield или Console.WriteLine ... Может быть, из-за столь быстрого цикла результаты искажены. –
Какая операционная система вы протестировали? –