Шаг 65.
Среда программирования Visual C++.
Создание рабочего потока

    На этом шаге мы рассмотрим алгоритм создания рабочего потока.

    Для рабочего потока необходимо написать код управляющей функции, предназначенной для реализации основной задачи потока. Ее адрес передается в качестве параметра функции AfxBeginThread(). Управляющая функция имеет следующий синтаксис:

    UINT MyControllingFunction(LPVOID pParam);

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

    Объявление соответствующей версии функции AfxBeginThread() имеет следующий вид:

  CWinThread* AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,
  int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, 
  DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);

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

    Функция AfxBeginThread() создает новый объект CWinThread, вызывает функцию CreateThread() для запуска потока и возвращает указатель на него. В ходе этой процедуры проводятся проверки, подтверждающие правильность освобождения всех объектов при возникновении сбоя на каком-либо этапе создания. Завершается поток самостоятельно, если функция потока содержит оператор return или при вызове глобальной функции AfxEndThread(). Возвращаемое значение в общем случае указывает на причину завершения. По существующей традиции при успешном завершении функция возвращает ноль, а ненулевое значение содержит код ошибки.

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

    Создадим класс CTimer, инкапсулирующий таймер. В этом классе для хранения времени будет создана защищенная MFC-переменная CTime и открытый указатель CWinThread, позволяющий oпределить, ссылается ли объект CTimer на активный поток.

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

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

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

    Текст измененного приложения можно взять здесь (64,9 Кб).

    На следующем шаге мы рассмотрим создание потока пользовательского интерфейса.




Предыдущий шаг Содержание Следующий шаг