MFC中创建子线程

_beginthreadex创建子线程

纯 C 运行库函数,不依赖 MFC 类,跨平台也能用,写法最简单,适合大多数简单任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 线程函数(必须是全局函数 / 静态成员函数)
UINT __cdecl MyThreadFunc(LPVOID pParam)
{
// 子线程逻辑
MessageBox(NULL, L"子线程运行中", L"提示", MB_OK);
return 0;
}

// 创建线程
void CMyDlg::OnBtnCreateThread()
{
// 创建线程,返回线程句柄
HANDLE hThread = (HANDLE)_beginthreadex(
NULL, // 安全属性
0, // 栈大小,0=默认
MyThreadFunc, // 线程函数
NULL, // 传入参数
0, // 立即运行
NULL // 线程ID
);

// 用完记得关闭句柄(不关闭会泄漏)
CloseHandle(hThread);
}

优点

  • 写法最简单,轻量
  • 不依赖 MFC 框架,通用

缺点

  • 线程函数不能是普通成员函数(必须全局 / 静态)
  • 没有 MFC 封装,需要自己管理句柄、同步

AfxBeginThread创建子线程 MFC 专用

MFC 官方封装的线程函数,专门给 MFC 程序用,最常用、最省心

MFC 把线程分成两种:

  1. 工作线程(后台计算、耗时任务,无界面)
  2. UI 线程(带消息循环,可创建窗口)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 线程函数(全局 / 静态成员函数)
UINT MyWorkThread(LPVOID pParam)
{
// 子线程任务
Sleep(3000);
AfxMessageBox(L"MFC 工作线程完成");
return 0;
}

// 创建
void CMyDlg::OnBtnCreateThread()
{
// 一行代码创建,自动管理
CWinThread* pThread = AfxBeginThread(
MyWorkThread, // 线程函数
NULL, // 参数
THREAD_PRIORITY_NORMAL, // 优先级
0, // 栈大小
0 // 立即运行
);
}

UI 线程(极少用,需要窗口才用)

继承 CWinThread 实现,自带消息循环。

优点

  • MFC 原生,一行创建
  • 自动管理线程生命周期
  • 支持工作线程 + UI 线程

缺点

  • 线程函数依然必须是全局 / 静态函数
  • 子线程不能直接操作 UI 控件(会崩溃)

std::thread

VS2013 及以上,强烈推荐,语法最优雅,支持直接传普通成员函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
// 类成员函数作为线程函数
void CMyDlg::MyThreadFunc()
{
AfxMessageBox(L"C++11 线程运行");
}

// 创建线程
void CMyDlg::OnBtnCreateThread()
{
// 直接绑定成员函数 + this指针
std::thread t(&CMyDlg::MyThreadFunc, this);
t.detach(); // 分离线程(或 t.join() 等待结束)
}

优点

  • C++ 标准,跨平台
  • 可以直接用类成员函数,不用全局 / 静态
  • 语法简洁、现代

缺点

  • 需要 VS2013+ 支持 C++11
  • 依然不能在子线程直接操作 MFC UI