管理线程引用

本文包含有关使用 Shell 轻型实用工具函数中的函数管理线程引用的信息。

当父线程必须在子线程的生存期内保持活动状态时,会出现这种情况。 例如,如果组件对象模型 (COM) 对象在父线程上创建并封送给子线程,则父线程不能在子线程之前终止。 为此,Shell 提供了这些函数。

如此处所述,在父线程中使用这些函数。

  1. 按照 ThreadProc 函数的形式声明应用程序定义的线程过程。

    DWORD WINAPI ThreadProc(LPVOID lpParameter);
    
  2. ThreadProc 中,调用 SHCreateThreadRef 以创建对线程的引用。 这会提供指向 IUnknown 实例的指针。 此 IUnknown 使用 pcRef 指向的值来维护引用计数。 只要此计数大于 0,线程就保持活动状态。

  3. 使用该指向 IUnknown 的指针,在 ThreadProc 中调用 SHSetThreadRef。 这会设置引用,以便对 SHGetThreadRef 的后续调用具有检索内容。

  4. 如果 ThreadProc 创建了另一个线程,该线程的 ThreadProc 可以使用指向 SHCreateThreadRef 获取的 IUnknown 的指针调用 SHGetThreadRef。 这会递增 SHCreateThreadRef 中的 pcRef 参数指向的引用计数。

  5. 创建线程。 这通常通过调用 SHCreateThread,在 pfnThreadProc 参数中传递一个指向 ThreadProc 的指针来完成。 此外,在 dwFlags 参数中传递 CTF_THREAD_REF 标志。 只要 ThreadProc 正在执行,线程就处于活动状态。

  6. 创建子线程时,在调用其 SHCreateThread 时,将 dwFlags 参数中的 CTF_REF_COUNTED 标志传递。

  7. 随着子线程完成并释放,父线程的 pcRef 指向的值会减少。 完成所有子线程后,原始 ThreadProc 可以完成并释放最终线程引用,将引用计数降至 0。 此时,将释放对 SHCreateThread 打开的原始线程的引用,并完成该线程。

另一个相关函数是 SHReleaseThreadRef。 如果线程是使用带有 CTF_THREAD_REF 标志的 SHCreateThread 创建的,则 ThreadProc 会调用此函数。 但是, ThreadProc 不需要隐式执行此操作。 只需在通过 SHCreateThreadRef 获取的指向 IUnknown 的指针上调用 IUnknown::Release