Поделиться через


Управление ссылками на потоки

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

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

Используйте эти функции в родительском потоке, как описано здесь.

  1. Объявите процедуру потока, определяемую приложением, в соответствии с формой функции ThreadProc.

    DWORD WINAPI ThreadProc(LPVOID lpParameter);
    
  2. В ThreadProcвызовите SHCreateThreadRef, чтобы создать ссылку на поток. Это обеспечивает указатель на экземпляр IUnknown. Этот IUnknown использует значение, на которое ссылается pcRef, для поддержания счетчика ссылок. Пока это число больше 0, поток остается активным.

  3. Используя этот указатель на IUnknown, вызовите SHSetThreadRef в ThreadProc. Это задает ссылку, чтобы последующие вызовы SHGetThreadRef могли что-то получить.

  4. ЕслиthreadProcсоздает другой поток, ThreadProc потока может вызывать SHGetThreadRef указателем на IUnknown, полученной SHCreateThreadRef. Это увеличивает число ссылок, на которое указывает параметр pcRef в SHCreateThreadRef.

  5. Создайте поток. Обычно это делается путем вызова SHCreateThread, передав указатель на ThreadProc в параметре pfnThreadProc. Кроме того, передайте флаг CTF_THREAD_REF в параметре dwFlags. Поток остаётся активным, пока выполняется процедура ThreadProc.

  6. При создании дочернего потока передайте флаг CTF_REF_COUNTED в параметре dwFlags в вызове SHCreateThread.

  7. По мере завершения и освобождения дочерних потоков значение, на которое указывает родительского потока, уменьшается. После завершения всех дочерних потоков исходная ThreadProc может завершить и освободить последнюю ссылку на поток, сводя счетчик ссылок до 0. На этом этапе ссылка на исходный поток, открытый SHCreateThread, освобождается, и поток завершается.

Другая связанная функция — SHReleaseThreadRef. Эта функция вызывается ThreadProc, если поток был создан с помощью SHCreateThread с флагом CTF_THREAD_REF. Однако ThreadProc не обязана делать это неявно. Вызов IUnknown::Release на указатель на IUnknown, полученный через SHCreateThreadRef, это все, что необходимо сделать.