понедельник, 8 ноября 2010 г.

Следствия из алгоритма планировщика: засыпание помогает не всегда

Это перевод Consequences of the scheduling algorithm: Sleeping doesn't always help. Автор: Реймонд Чен.

Чаще всего я вижу проблемы, обратные к теме "поток с низким приоритетом может работать даже когда в системе есть активный поток с высоким приоритетом". А именно: люди, которые думают, что Sleep(0) является чистым способом отдать процессор (yield). Например, у них могли закончиться вещи, которые можно делать, и они просто хотят, чтобы другой поток делал работу.

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

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

Поэтому, если вы вызываете Sleep(0) как неэффективный выход, то этим вы заблокируете потоки с низким приоритетом. Это означает, что различные фоновые задачи (вроде индексации) практически не будут работать, потому что ваша программа занимает весь процессор. Более того, из-за того, что вы никогда не отдаёте процессор, машина не может уйти в режим пониженного энергопотребления. Ноутбуки будут быстро есть ресурс батарее и греться.

Лучше, что тут можно сделать - ждать новой работы на каком-нибудь синхронизирующем объекте, так что ваш поток будет спать, не тратя процессор, пока не появится новая работа для него. Если вы не можете сделать это по какой-то причине, то хотя бы засыпайте на ненулевое время. Таким образом, на это короткое время, пока вы спите и ваш поток не готов к выполнению, другие потоки (включая низкоприоритетные) получают шанс на выполнение (это также уменьшит энергопотребление, хотя и не так, как ожидание на подходящем объекте синхронизации).

1 комментарий:

  1. Отличная статья с выводами в виде двух возможных решений. Всегда выбирал объект синхронизации для этого случая, теперь знаю почему это хорошо )

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.