Назначение Thread.Sleep (1)? - PullRequest
       4

Назначение Thread.Sleep (1)?

3 голосов
/ 20 декабря 2011

Я читал об основах многопоточности, и на сайте msdn я нашел этот фрагмент кода.

    // 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 миллисекунд?

Если речь идет исключительно об использовании процессора, вот такой же Вопрос о Thread.Sleep .

Любые комментарии приветствуются.

Спасибо.

Ответы [ 5 ]

7 голосов
/ 20 декабря 2011

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

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

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

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


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

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

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

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

4 голосов
/ 20 декабря 2011

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

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

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

2 голосов
/ 20 декабря 2011

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

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

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

0 голосов
/ 21 декабря 2011

Интересная вещь, которую я заметил сегодня. Прерывание потока создает ThreadInterruptedException. Я пытался поймать исключение, но не смог по какой-то причине. Мой коллега порекомендовал мне поставить Thread.Sleep(1) перед оператором catch, и это позволило мне поймать 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 голосов
/ 20 декабря 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...