Поток с наименьшим приоритетом вызывается большее количество раз

Рейтинг: 3Ответов: 2Опубликовано: 31.10.2014

В следующем коде 5 потоков с разными приоритетами конкурируют за доступ к ЦП с 8 ядрами. Каждый поток увеличивает свой счетчик.

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 ядрами выдает:

 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

Почему такая разница?

Ответы

▲ 3

Я думаю, всё очень просто: сигнал finish дошёл до потока с наименьшим приоритетом позже всех, из-за чего он поработал дольше всех. Вы добавьте ещё метрику - длительность работы потока.

Разница на двух процессорной системе как раз из-за нехватки ресурсов. Я так понимаю, что приоритет начинает играть свою роль, когда происходит нехватка процессорных ресурсов, и в этом случае система начинает раздавать их в зависимости от приоритетов. Если же есть свободные ресурсы - то приоритеты не влияют.

▲ 2

@Чад, а откуда появился сигнал finish?

Это же просто переменная. Мне кажется, все проще.

Потоки запускаются в цикле, в порядке повышения приоритета. Поэтому первый запущенный, при условии, что свободных ядер хватает, проработает дольше.

А "сигнал" (на самом деле новое значение переменной) все потоки увидят одновременно.

Я бы добавил переменную start, которой бы все потоки дожидались перед циклом с провевкой finish.

 while(!start);
 while(!finish)
   counts[(int)iThread]++;

а в main

 for (...) 
    // запуск потоков
 start = true;