2011-12-19 2 views
3

Я читал некоторые основы потоковой передачи, и на веб-сайте msdn я нашел этот фрагмент кода.Назначение Thread.Sleep (1)?

// Put the main thread to sleep for 1 millisecond to 
    // allow the worker thread to do some work: 
    Thread.Sleep(1); 

Вот ссылка на страницу: http://msdn.microsoft.com/en-us/library/7a2f3ay4(v=vs.80).aspx.

Почему основная нить спит в течение 1 миллисекунды? Будет ли вторичный поток не запускать свои задачи, если основной поток будет постоянно работать? Или это пример, предназначенный для задачи, которая занимает 1 миллисекунду? Как и в случае, если задача обычно занимает 5 секунд, чтобы завершить основной поток, следует спать в течение 5000 миллисекунд?

Если это касается использования ЦП, то это аналогичный Question about Thread.Sleep.

Любые комментарии будут оценены.

Спасибо.

+0

Джо Albahari пишет об этой самой проблеме, здесь: http://www.albahari.com/threading/part2.aspx – dash

+0

Спасибо, что выглядит как всю информацию, которая мне понадобится по этой проблеме. – YahooMania

ответ

7

1 в этом коде не является особо особенным; он будет всегда заканчивает спать дольше, чем все, что не так точно, и отказ от вашего временного фрагмента не равен никакой гарантии от ОС, когда вы его получите.

Назначение параметра времени в Thread.Sleep() заключается в том, что ваша нить даст для не менее, что количество времени, примерно.

Так что код просто явно отказывается от своего временного интервала. Вообще говоря, такой бит кода не нужен, так как ОС будет управлять вашими потоками для вас, превентивно прерывая их для работы с другими потоками.

Такой код часто используется в «примерах пронизывающих», где автор хочет, чтобы заставить некоторое искусственное возникновение, чтобы доказать какое-либо условие гонки, или тому подобное (что, как представляется, имеет место в вашем примере)


Как отмечалось в ответе Джона Ханны на этот же вопрос, существует тонкое, но важное различие между Sleep(0) и Sleep(1) (или любым другим ненулевым числом), и, как намекает ChrisF, это может быть важно в некоторых ситуациях с потоками.

Оба из них связаны с приоритетами потоков; В потоках могут быть заданы более высокие/более низкие приоритеты, так что потоки с более низким приоритетом будут никогда не выполнять, если есть потоки с более высоким приоритетом, которые имеют какую-либо работу. В таком случае может потребоваться Sleep(1) ... Однако ...

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

Это не обычно что-то вам когда-нибудь нужно беспокоиться; приоритет по умолчанию - это «нормальный» приоритет, и в большинстве случаев его не следует изменять. Подъем или опускание имеет многочисленные последствия.

+0

Итак, что бит кода действительно наносит ущерб целям потоков? Цель состоит в том, чтобы выполнить сразу несколько задач, не дожидаясь завершения друг друга. Лучше не использовать это? – YahooMania

+0

@YahooMania Нет, это очень важно сделать в некоторых случаях. –

+0

@YahooMania Но вы не обязательно все, что может столкнуться с такой ситуацией, за пределами примеров потоков. Этот бит кода существует, чтобы помочь проиллюстрировать точку. –

0

Это только ради примера - они хотят удостовериться, что рабочий поток имеет возможность напечатать «рабочий поток: работа ...» по крайней мере один раз, прежде чем основной поток убьет его.

Как и следовало ожидать, это важно в этом примере, особенно потому, что если вы работаете на однопроцессорной машине, основной поток не может отказаться от процессора, убивая фоновый поток, прежде чем он сможет повторить итерацию ,

2

Если основная нить не спит вообще, другие нити не смогут работать вообще.

Вставка Sleep из любой длины позволяет другим потокам некоторое время обработки. Использование небольшого значения (в этом случае 1 миллисекунда) означает, что основной поток не задерживается. Вы можете использовать Sleep(0), но, как отмечает Джон Ханна, имеет значение, отличное от Sleep(1) (или даже любое положительное значение), поскольку он позволяет запускать нити равного приоритета.

Если задача занимает 5 секунд, основной поток будет спать в течение всего 5000 миллисекунд, но разбросаны в течение более длительного периода.

+0

Не совсем верно. Минимум равен 0, но в этом случае он не даст нисходящим потокам. –

4

Thread.Sleep(0) откажется от остальной части потока, если поток с равным приоритетом готов к расписанию.

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

http://www.bluebytesoftware.com/blog/PermaLink,guid,1c013d42-c983-4102-9233-ca54b8f3d1a1.aspx имеет больше на этом.

0

Интересная вещь, которую я заметил сегодня. Прерывание нити вызывает ThreadInterruptedException. Я пытался поймать исключение, но не мог по какой-то причине. Мой коллега рекомендовал, чтобы я положил Thread.Sleep(1) до выписки, и это позволило мне поймать ThreadInterruptedException.

 // Start the listener 
     tcpListener_ = new TcpListener(ipAddress[0], int.Parse(portNumber_)); 
     tcpListener_.Start(); 
     try 
     { 
      // Wait for client connection 
      while (true) 
      { 
       // Wait for the new connection from the client 
       if (tcpListener_.Pending()) 
       { 
        socket_ = tcpListener_.AcceptSocket(); 
        changeState(InstrumentState.Connected); 

        readSocket(); 
       } 
       Thread.Sleep(1); 
      } 
     } 

     catch (ThreadInterruptedException) { } 

     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message, "Contineo", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      Console.WriteLine(ex.StackTrace); 
     } 

Некоторые другие классы ...

 if (instrumentThread_ != null) 
     { 
      instrumentThread_.Interrupt(); 
      instrumentThread_ = null; 
     } 
+0

Его также можно было поймать, если вы вытащили тест 'Pending()' и просто отпустили блок 'AcceptSocket()' до 'Start'. Причина - расширение моего ответа.В потоке не будет наложено 'ThreadInterruptedException', пока он не блокирует или не отказывается от своего временного фрагмента (а не просто заканчивается его квантами и возвращается к ожиданию следующих квантов), которые' Thread.Sleep (1) 'вызывает, но' Thread.Sleep (0) 'не делает. Ввод монитора или ожидание на мероприятии также дал бы ему шанс бросить. –

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