2013-11-08 6 views
1

Я только начал изучать «Threading in C#». Я нашел в книге, что Thread.Sleep (0) немедленно отказывается от текущего временного фрагмента потока, добровольно передавая CPU другим потокам.Thread.Sleep (0) не работает должным образом

Когда я написал несколько строк кода, чтобы проверить его. Я не получил ожидаемого результата. Вот код, который я написал.

class Program 
{ 
    static void Main(string[] args) 
    { 
     Thread.CurrentThread.Name = "Thread A(main thread)"; 

     Thread thread = new Thread(PrintNumber); 
     thread.Name = "Thread B"; 
     thread.Start(); 

     for (int i = 0; i < 40; i++) 
     { 
      Console.WriteLine("{0} | i = {1}", Thread.CurrentThread.Name, i); 
     } 
    } 

    void PrintNumber() 
    { 
     for (int i = 0; i < 40; i++) 
     { 
      Console.WriteLine("{0} | i = {1}", Thread.CurrentThread.Name, i); 

      if (i == 4) 
      { 
       Thread.Sleep(0); 
      } 
     } 
    } 
} 

По моему разумению это будет печатать до 4 в потоке B, то он возобновит нить A. Следующий график нити непредсказуемо. Но этого не происходит. В то время как речь идет о потоке B впервые, иногда он печатает до 6, иногда 8 означает совершенно непредсказуемый.

Так ли моя концепция Theread.Sleep (0) неверна? Может кто-то пожалуйста, уточнить понятие

+0

Я нашел эту ветку во время поиска. Я забыл об этом и подумал, что он описывает разные проблемы. Теперь я вижу, что он задает почти такой же вопрос, как и я. Извините за повторение. – amitavak

ответ

3

Если делает высвободит Нарезать нити, что не означает, что вы можете предсказать, где он будет - он может пойти любой процесс на компьютере. В частности, предполагая, что у вас многоядерная машина, другой поток может обслуживаться полностью другим ядром. В коде, как показано, также вероятно, что "Thread B" даже не получил начато до ближайшего Main 's loop. Запуск потока не мгновенен.

Есть очень мало сценариев, в которых Thread.Sleep(0) собирается быть полезным для вас, и все эти сценарии будут включать обширные знания моделей многопоточности и памяти.

+0

Я не могу предсказать, какой поток получит временной срез, когда я использую Thread.Sleep (0) в потоке. Но может ли это быть тот же самый поток, который снова набирает время? – amitavak

+0

@amitavak уверен, почему бы и нет? –

2

Thread.Yield() гарантирует, что следующая выполняемая нить не является текущей нитью.

+0

Я уверен, что Thread.Sleep (0) делает то же самое. Единственное отличие состоит в том, что Thread.Yield() будет отбрасывать срез времени только для потока, выполняющегося на одном процессоре. – amitavak

+0

Очень вероятно, но не гарантируется. Вот почему 'Thread.Yield()' возвращает 'bool' – Moho

+0

Хорошая точка. Я этого не заметил. Спасибо. – amitavak

Смежные вопросы