多线程处理:创建辅助线程

辅助线程通常用于处理后台任务,用户不必等待即可继续使用应用程序。 重新计算和后台打印等任务是很好的辅助线程示例。 本主题详细介绍创建辅助线程所需的步骤。 主题包括:

  • 启动线程

  • 实现控制函数

  • 示例

创建辅助线程是一个相对较为简单的任务。 只需两步即可以使线程运行:实现控制函数和启动线程。 不必从 CWinThread 派生类。 如果需要特殊版本的 CWinThread,可以从该类派生,但大多数简单辅助线程都不需要这样做。 无需修改即可使用 CWinThread

启动线程

AfxBeginThread 有两个重载版本:一个用于用户界面线程,一个用于辅助线程。 若要开始执行辅助线程,请调用 AfxBeginThread,并提供下列信息:

  • 控制函数的地址。

  • 要传递到控制函数的参数。

  • (可选)所需的线程优先级。 默认值为正常优先级。 有关可用的优先级级别的更多信息,请参见 Windows SDK 中的 SetThreadPriority

  • (可选)所需的线程堆栈大小。 默认值与创建线程的堆栈大小相同。

  • (可选)CREATE_SUSPENDED,如果希望在挂起状态中创建线程。 默认值为 0,即正常启动线程。

  • (可选)所需的安全特性。 默认值与父线程具有相同的访问权。 有关此安全信息格式的更多信息,请参见 Windows SDK 中的 SECURITY_ATTRIBUTES

AfxBeginThread 为您创建和初始化 CWinThread 对象、启动该对象并返回其地址,以便以后引用。 在整个过程中进行检查,确保假如创建过程的任何部分出现故障,所有对象都能被正确地解除分配。

实现控制函数

控制函数定义线程。 输入此函数后线程开始,此函数退出时线程终止。 此函数的原型应为:

UINT MyControllingFunction( LPVOID pParam );

该参数为单个值。 函数在此参数中接收的值是在创建线程对象时传递到构造函数的值。 控制函数可以用其选择的任何方式解释此值。 它可以视为标量值,或指向包含多个参数的结构的指针,也可以忽略。 如果参数引用结构,则既可以使用该结构将数据从调用方传递到线程,也可以用该结构将数据从线程传递回调用方。 如果使用此类结构将数据传递回调用方,结果准备就绪时,线程需要通知调用方。 有关从辅助线程到调用方进行通信的信息,请参见多线程处理:编程提示

函数终止后,应该返回指示终止原因的 UINT 值。 一般情况下,此退出代码为 0 指示成功;若为其他值,则指示不同类型的错误。 这只依赖于实现。 某些线程可以维护对象的使用计数,并返回该对象的当前使用数。 有关应用程序如何检索此值的信息,请参见多线程处理:终止线程

在用 MFC 库编写的多线程程序中有一些操作限制。 有关这些限制的说明以及使用线程的其他提示,请参见多线程处理:编程提示

控制函数示例

下面的示例演示如何定义控制函数,以及如何从程序的其他部分使用此函数。

UINT MyThreadProc( LPVOID pParam )
{
    CMyObject* pObject = (CMyObject*)pParam;

    if (pObject == NULL ||
        !pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))
    return 1;   // if pObject is not valid

    // do something with 'pObject'

    return 0;   // thread completed successfully
}

// inside a different function in the program
.
.
.
pNewObject = new CMyObject;
AfxBeginThread(MyThreadProc, pNewObject);
.
.
.

您想进一步了解什么?

请参见

概念

使用 C++ 和 MFC 进行多线程编程