Джонсон Харт - Системное программирование в среде Windows
- Название:Системное программирование в среде Windows
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2005
- Город:Москва • Санкт-Петербург • Киев
- ISBN:5-8459-0879-5
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Джонсон Харт - Системное программирование в среде Windows краткое содержание
Эта книга посвящена вопросам разработки приложений с использованием интерфейса прикладного программирования операционных систем компании Microsoft (Windows 9х, Windows XP, Windows 2000 и Windows Server 2003). Основное внимание уделяется базовым системным службам, включая управление файловой системой, процессами и потоками, взаимодействие между процессами, сетевое программирование и синхронизацию. Рассматривается методика переноса приложений, написанных в среде Win32, в среду Win64. Подробно описываются все аспекты системы безопасности Windows и ее практического применения. Изобилие реальных примеров, доступных также и на Web-сайте книги, существенно упрощает усвоение материала.
Книга ориентирована на разработчиков и программистов, как высокой квалификации, так и начинающих, а также будет полезна для студентов соответствующих специальностей.
Системное программирование в среде Windows - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
• Поток, независимо от его состояния, может быть приостановлен (suspended), и приостановленный поток не будет запущен, даже если он находится в состоянии готовности. В случае приостановки выполняющегося потока, независимо от того, по собственной ли инициативе или по инициативе потока, выполняющегося на другом процессоре, он переводится в состояние готовности.
• Поток переходит в состояние завершения (terminated state) тогда, когда его выполнение завершается, и остается в этом состоянии до тех пор, пока остается открытым хотя бы один из ее дескрипторов. Это позволяет другим потокам запрашивать состояние данного потока и его код завершения.
Возможные ловушки и распространенные ошибки
Существует ряд факторов, о которых следует всегда помнить при разработке многопоточных программ. Пренебрежение некоторыми базовыми принципами может привести к появлению серьезных дефектов в программе, и лучше заранее стремиться к тому, чтобы не допустить ошибок, чем впоследствии затрачивать время на тестирование и отладку программ.
Существенно то, что потоки выполняются в асинхронном режиме. По отношению к ним не действует никакая система упорядочения, если только вы не создали ее явно. Именно асинхронное поведение потоков делает их столь полезными, однако при отсутствии должного внимания можно столкнуться с серьезными трудностями.
Часть соответствующих рекомендаций представлена ниже, а остальные будут даваться по мере изложения материала в последующих главах.
• Не делайте никаких предположений относительно очередности выполнения родительских и дочерних потоков. Вполне возможно, что дочерний поток будет выполняться вплоть до своего завершения, прежде чем родительский поток вернется из функции CreateThread, или наоборот, дочерний поток может вообще не выполняться в течение длительного периода времени. В случае же SMP-систем возможно параллельное выполнение родительского и одного или нескольких дочерних потоков.
• Убедитесь в том, что до вызова функции CreateThread были завершены все действия по инициализации данных, необходимые для правильной работы дочернего потока, либо приостановите поток или же воспользуйтесь любой другой подходящей методикой. Несвоевременная инициализация данных, требуемых дочерним потоком, может создать "условия состязаний" ("race conditions"), суть которых заключается в том, что родительский поток "состязается" с дочерним, чтобы инициализировать данные до того, как они начнут использоваться дочерним потоком.
• Проследите за тем, чтобы каждый отдельный поток имел собственную структуру данных, переданную ему через параметр функции потока. Не делайте никаких предположений относительно очередности завершения дочерних потоков (иначе можете столкнуться с другой разновидностью "проблемы состязаний").
• Выполнение любого потока может быть прервано в любой момент, и точно так же выполнение любого потока в любой момент может быть возобновлено.
• Не пользуйтесь приоритетами потоков в качестве замены явной синхронизации.
• Никогда не прибегайте к аргументации наподобие "вряд ли это может произойти" при анализе корректности программы. Если что-то может произойти, оно обязательно произойдет, причем тогда, когда вы меньше всего этого ожидаете.
• В еще большей степени, чем в случае однопоточных программ, справедливо утверждение о том, что, хотя тестирование и необходимо, но его одного еще не достаточно для проверки корректности многопоточной программы. Довольно часто программы способны успешно пройти через самые различные тесты, несмотря на наличие в них дефектов. Ничто не может заменить тщательно выполненных проектирования, реализации и анализа кода.
• Поведение многопоточных программ может заметно меняться в зависимости от быстродействия и количества процессоров, версии ОС и множества других факторов. Тестирование программы в самых различных системах помогает выявлению всевозможных дефектов, но предыдущее предостережение остается в силе.
• Убедитесь в том, что предусмотрели для потоков достаточно большой объем стека, хотя заданного по умолчанию стека размером 1 Мбайт в большинстве случаев вам должно хватить.
• Потоки следует использовать только тогда, когда это действительно необходимо. Таким образом, если по самой своей природе некоторые операции допускают параллелизм, то каждое такое действие может быть представлено потоком. В то же время, если операциям присуща очередность, то потоки лишь усложнят программу, а связанный с ними расход системных ресурсов может привести к снижению производительности.
• К счастью, чаще всего корректно работают самые простые программы и те, отличительной чертой которых является элегантность. При малейшей возможности избегайте усложнения программ.
Ожидание в течение конечного интервала времени
Наконец, рассмотрим функцию Sleep, позволяющую потоку отказаться от процессора и перейти из состояния выполнения в состояние ожидания, которое будет длиться в течение заданного промежутка времени. Например, выполнение задачи потоком может продолжаться в течение некоторого периода времени, после чего поток приостанавливается. По истечении периода ожидания планировщик вновь переводит поток в состояние готовности. Именно эта техника применена в одной из программ в главе 11 (программа 11.4).
VOID Sleep(DWORD dwMilliseconds)
Длительность интервала ожидания указывается в миллисекундах, и одним из ее возможных значений является INFINITE, что соответствует бесконечному периоду ожидания, при котором выполнение приостанавливается на неопределенное время. Значению 0 соответствует отказ потока от оставшейся части отведенного ей временного промежутка; в этом случае ядро переводит поток из состояния выполнения в состояние готовности, как показано на рис. 7.4.
Функция SwitchToThread предоставляет потоку еще один способ уступить процессор другому потоку из числа тех, которые находятся в состоянии готовности, если таковые имеются.
UNIX-функция sleep аналогична функции Sleep, но длительность периода ожидания измеряется в секундах. Чтобы получить миллисекундное разрешение, используйте функции select или poll без дескрипторов файлов.
Облегченные потоки
Примечание
Облегченные потоки относятся к специальной тематике. Ознакомьтесь с комментарием, включенным в конце первого абзаца приведенного ниже списка, и решите для себя, стоит ли вам читать данный раздел.
Облегченные потоки (fibers), как говорит само их название, являются элементами потока. Точнее, облегченный поток — это единица выполнения в контексте потока, планируемая приложением, а не ядром. В потоке могут быть запланированы несколько облегченных потоков, и облегченные потоки сами определяют, какой из них должен выполняться следующим. Облегченные потоки имеют независимые стеки, но во всем остальном выполняются исключительно в контексте потока, имея, например, доступ к TLS потока и любому мьютексу [27] Как объясняется в следующей главе, мьютексы — это объекты синхронизации, владельцами которых могут быть потоки.
, владельцем которого является данный поток. Более того, вся работа с облегченными потоками осуществляется вне ядра исключительно в пользовательском пространстве. Между потоками и облегченными потоками существуют многочисленные отличия.
Интервал:
Закладка: