Основной поток
Основной поток программы Cursor ведет себя почти так же, как и основные потоки всех остальных программ, рассмотренных нами. Он инициализирует DirectDraw, создает поверхности приложения, строит очередной кадр во вторичном буфере и переключает страницы для его отображения. Чтобы обеспечить работу потока ввода, нам придется возложить на основной поток следующие дополнительные задачи:
- создание и запуск потока ввода;
- обновление курсора перед каждым переключением страниц;
- синхронизацию с потоком ввода;
- завершение потока ввода.
Основной поток должен в какой-то момент создать и запустить поток ввода (хотя создание и запуск потока можно выполнить одновременно, на самом деле это две разные операции). Поток должен быть запущен в начале работы программы, но следует позаботиться о том, чтобы это не произошло слишком рано. Преждевременный запуск может привести к тому, что поток ввода обнаружит ввод от мыши и попытается обновить курсор до того, как основной поток закончит инициализацию DirectDraw.
Основной поток также должен обновлять курсор перед каждым переключением страниц. После подготовки нового кадра во вторичном буфере, но до переключения страниц, основной поток должен скопировать курсор во вторичный буфер. Однако перед тем, как рисовать курсор, необходимо сохранить соответствующую область вторичного буфера, чтобы поток ввода смог позднее стереть изображение курсора.
Чтобы основной поток не пытался обновить первичную поверхность одновременно с потоком ввода, мы должны синхронизировать работу этих двух потоков. Для основного потока это означает, что операция вывода курсора (во вторичный буфер) и переключение страниц может выполняться лишь после получения доступа к критической секции, используемой для синхронизации потока. Обратите внимание: подготовка вторичного буфера не входит в критическую секцию, потому что основной поток вполне может готовить вторичный буфер, пока поток ввода обновляет содержимое первичной поверхности.
Наконец, основной поток должен предупредить поток ввода о завершении приложения. Помните — поток ввода работает независимо от основного потока. Без извещения со стороны основного потока он не будет знать о том, что приложение собирается завершиться. Кроме того, основной поток не может просто остановить работу потока ввода; поток ввода должен завершиться сам при получении сигнала завершения от основного потока.