MFC线程-AfxBeginThread使用方法
前言
AfxBeginThread
是 MFC(Microsoft Foundation Classes,微软基础类库)中用于创建一个新线程的函数。它返回一个指向 CWinThread
类对象的指针,通过这个指针可以对创建出来的线程进行后续的操作和控制。
CWinThread* AFXAPI AfxBeginThread(
AFX_THREADPROC pfnThreadProc, LPVOID pParam,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);
参数说明
该函数接收一个 LPVOID
类型(也就是 void*
类型,可用于传递任意类型的指针)的参数,这个参数就是在调用 AfxBeginThread
时通过 pParam
参数传递进来的值,函数返回一个 UINT
值,一般可以根据线程执行的结果返回相应的状态码等信息。例如,返回 0
表示线程正常结束,返回其他非零值可以表示不同的结束状态(具体含义由程序员自行定义)。
pfnThreadProc 参数:类型为 AFX_THREADPROC,这是一个函数指针类型。它指向的函数就是新线程要执行的线程函数。线程函数的定义形式通常类似如下:
UINT MyThreadProc(LPVOID pParam);
pParam 参数:类型为 LPVOID,它是传递给线程函数(也就是 pfnThreadProc 所指向的函数)的参数。你可以将需要在线程内部使用的数据的指针通过这个参数传递进去,比如传递一个结构体指针,该结构体中包含了线程执行任务所需要的各种配置信息等。
nPriority 参数:类型为 int,默认值是 THREAD_PRIORITY_NORMAL。用于设置新创建线程的优先级。线程优先级决定了线程在系统中获取 CPU 时间片的相对机会,取值可以是一些预定义的常量,例如:
THREAD_PRIORITY_HIGHEST:最高优先级,线程有较高的机会获取 CPU 时间片来执行。
THREAD_PRIORITY_ABOVE_NORMAL:高于正常优先级,能比正常优先级的线程更优先获取到 CPU 资源。
THREAD_PRIORITY_NORMAL:正常优先级,系统按照常规的调度策略分配 CPU 时间片。
THREAD_PRIORITY_BELOW_NORMAL:低于正常优先级。
THREAD_PRIORITY_LOWEST:表示最低优先级,线程相对较难获取到 CPU 时间片,执行机会相对较少。
nStackSize 参数:类型为 UINT,默认值是 0。它指定了新线程的栈空间大小(以字节为单位)。如果设置为 0,系统会使用默认的栈大小来为线程分配栈空间。通常情况下,默认值就可以满足大多数需求,但在一些特殊场景下,比如线程中可能会有很深的函数调用层次或者大量的局部变量等情况,可能需要手动指定一个较大的栈空间大小。
dwCreateFlags 参数:类型为 DWORD,默认值是 0。用于指定线程的创建标志,常见的取值有:
CREATE_SUSPENDED:如果设置了这个标志,线程创建后会处于挂起状态,需要通过调用 CWinThread 对象的 ResumeThread 方法来启动线程,使其开始执行。
0:表示线程创建后立即开始执行。
lpSecurityAttrs 参数:类型为 LPSECURITY_ATTRIBUTES,默认值是 NULL。它用于设置线程的安全属性,比如指定线程的安全描述符等信息。在大多数普通应用场景中,传递 NULL 即可,使用系统默认的安全设置。
案例:
新建一个基于对话框的窗体,添加一个button控件(IDC_BUTTON_Thread1)和Edit控件(IDC_EDIT_ThreadParm1)。为Edit控件添加一个变量m_thread1Pam;
头文件:
CString m_thread1Pam;
int num = 0;
afx_msg void OnBnClickedButtonThread1();
//千万要注意线程函数是静态类函数成员
static UINT _cdecl pfnThreadProc(LPVOID lpararm);
CPP文件:
void CMFCThreadDlg::OnBnClickedButtonThread1()
{
// TODO: 在此添加控件通知处理程序代码
GetDlgItem(IDC_EDIT_ThreadParm1)->GetWindowText(m_thread1Pam);
num=_ttoi(m_thread1Pam);
GetDlgItem(IDC_EDIT_ThreadParm1)->SetWindowText(TEXT(""));
CWinThread* pThread = AfxBeginThread(pfnThreadProc, this);
if (pThread != NULL)
{
// 获取线程句柄,用于WaitForSingleObject函数
HANDLE hThread = pThread->m_hThread;
// 等待线程结束,获取线程的返回值
DWORD waitResult = WaitForSingleObject(hThread, INFINITE);
if (waitResult == WAIT_OBJECT_0)
{
AfxMessageBox(TEXT("线程正常退出"));
}
}
else
{
AfxMessageBox(TEXT("线程创建失败"));
}
}
//注意函数成员需要添加类CMFCThreadDlg::类头,不然会报LNK2019错误
UINT _cdecl CMFCThreadDlg::pfnThreadProc(LPVOID pParam)
{
CMFCThreadDlg* p = (CMFCThreadDlg*)pParam;
int a = p->num;
CString str;
str.Format(_T("输入数据:%d \n"), a);
TRACE(str);
return 0;
}