Чтение онлайн

на главную - закладки

Жанры

Системное программирование в среде Windows

Харт Джонсон М.

Шрифт:

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

• Планировщик переводит ожидающий поток в состояние готовности сразу же, как только соответствующие дескрипторы оказываются в сигнальном состоянии, хотя при этом поток фактически проходит через промежуточное переходное состояние (transition state). В подобных случаях принято говорить о том, что поток пробуждается (wakes).

• Не

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

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

• Поток переходит в состояние завершения (terminated state) тогда, когда его выполнение завершается, и остается в этом состоянии до тех пор, пока остается открытым хотя бы один из ее дескрипторов. Это позволяет другим потокам запрашивать состояние данного потока и его код завершения.

Возможные ловушки и распространенные ошибки

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

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

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

• Не делайте никаких предположений относительно очередности выполнения родительских и дочерних потоков. Вполне возможно, что дочерний поток будет выполняться вплоть до своего завершения, прежде чем родительский поток вернется из функции CreateThread, или наоборот, дочерний поток может вообще не выполняться в течение длительного периода времени. В случае же SMP-систем возможно параллельное выполнение родительского и одного или нескольких дочерних потоков.

• Убедитесь в том, что до вызова функции CreateThread были завершены все действия по инициализации данных, необходимые для правильной работы дочернего потока, либо приостановите поток или же воспользуйтесь любой другой подходящей методикой. Несвоевременная инициализация данных, требуемых дочерним потоком, может создать "условия состязаний" ("race conditions"), суть которых заключается в том, что родительский поток "состязается" с дочерним, чтобы инициализировать данные до того, как они начнут использоваться дочерним потоком.

• Проследите за тем, чтобы каждый отдельный поток имел собственную

структуру данных, переданную ему через параметр функции потока. Не делайте никаких предположений относительно очередности завершения дочерних потоков (иначе можете столкнуться с другой разновидностью "проблемы состязаний").

• Выполнение любого потока может быть прервано в любой момент, и точно так же выполнение любого потока в любой момент может быть возобновлено.

• Не пользуйтесь приоритетами потоков в качестве замены явной синхронизации.

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

• В еще большей степени, чем в случае однопоточных программ, справедливо утверждение о том, что, хотя тестирование и необходимо, но его одного еще не достаточно для проверки корректности многопоточной программы. Довольно часто программы способны успешно пройти через самые различные тесты, несмотря на наличие в них дефектов. Ничто не может заменить тщательно выполненных проектирования, реализации и анализа кода.

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

• Убедитесь в том, что предусмотрели для потоков достаточно большой объем стека, хотя заданного по умолчанию стека размером 1 Мбайт в большинстве случаев вам должно хватить.

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

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

Ожидание в течение конечного интервала времени

Наконец, рассмотрим функцию Sleep, позволяющую потоку отказаться от процессора и перейти из состояния выполнения в состояние ожидания, которое будет длиться в течение заданного промежутка времени. Например, выполнение задачи потоком может продолжаться в течение некоторого периода времени, после чего поток приостанавливается. По истечении периода ожидания планировщик вновь переводит поток в состояние готовности. Именно эта техника применена в одной из программ в главе 11 (программа 11.4). 

VOID Sleep(DWORD dwMilliseconds)
 

Длительность интервала ожидания указывается в миллисекундах, и одним из ее возможных значений является INFINITE, что соответствует бесконечному периоду ожидания, при котором выполнение приостанавливается на неопределенное время. Значению 0 соответствует отказ потока от оставшейся части отведенного ей временного промежутка; в этом случае ядро переводит поток из состояния выполнения в состояние готовности, как показано на рис. 7.4.

Поделиться:
Популярные книги

Неудержимый. Книга VIII

Боярский Андрей
8. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
6.00
рейтинг книги
Неудержимый. Книга VIII

Законы Рода. Том 6

Flow Ascold
6. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 6

Восход. Солнцев. Книга I

Скабер Артемий
1. Голос Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Восход. Солнцев. Книга I

Попаданка

Ахминеева Нина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Попаданка

Возлюби болезнь свою

Синельников Валерий Владимирович
Научно-образовательная:
психология
7.71
рейтинг книги
Возлюби болезнь свою

Кодекс Крови. Книга III

Борзых М.
3. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга III

Ротмистр Гордеев 2

Дашко Дмитрий
2. Ротмистр Гордеев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Ротмистр Гордеев 2

Идеальный мир для Лекаря 5

Сапфир Олег
5. Лекарь
Фантастика:
фэнтези
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 5

Адвокат Империи 3

Карелин Сергей Витальевич
3. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Адвокат Империи 3

Жребий некроманта 3

Решетов Евгений Валерьевич
3. Жребий некроманта
Фантастика:
боевая фантастика
5.56
рейтинг книги
Жребий некроманта 3

Город драконов

Звездная Елена
1. Город драконов
Фантастика:
фэнтези
6.80
рейтинг книги
Город драконов

Убивать, чтобы жить

Бор Жорж
1. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать, чтобы жить

Инквизитор Тьмы 2

Шмаков Алексей Семенович
2. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы 2

Беглец

Бубела Олег Николаевич
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Беглец