在最近的一个工程中,涉及到大量的图像处理的计算,当进行图像处理时程序界面会显示未响应。由于正在处理计算,程序使用的是单线程,因此无法进行其他操作。
考虑使用多线程运算,将计算的部分放入新的线程中。在此使用一个简单的例子进行实现。
在MFC中,多线程依靠AfxBeginThread函数实现。该函数可用于创建界面和工作线程,对于工作线程,其原型为:
CWinThread* AFXAPI AfxBeginThread(
AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
int nPriority,
UINT nStackSize,
DWORD dwCreateFlags,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)
其中:
参数1 线程的入口函数,声明一定要如下: UINT MyThreadFunction( LPVOID pParam ); 参数2 传递入线程的参数,注意它的类型为:LPVOID,所以我们可以传递一个结构体入线程;参数3、4、5分别指定线程的优先级、堆栈大小、创建标识、安全属性,含义同用户界面线程。
注意其中的参数1,就是我们要在该线程中启动的函数名了。此外还是用到了SuspendThread()函数用于暂停线程;ResumeThread()函数用于恢复线程。首先预览一下程序界面:
开始动手!首先定义一个线程对象写一个死循环函数:
CWinThread* mythread;
//死循环函数
UINT EndlessLoop (LPVOID lpParam)
{
int i = 1;
for (;;)
{
i += i;
}
return 0;
}
在主界面上的计算按钮中添加代码,按此按钮即启动线程:
void CSingleThreadDlg::OnBnClickedStartthread()
{
//启动线程函数
mythread = AfxBeginThread(
EndlessLoop,//即上面定义的函数
NULL
);
}
暂停线程使用SuspendThread()函数,在暂停线程按钮中添加代码:
void CSingleThreadDlg::OnBnClickedPausethread()
{
// TODO: 在此添加控件通知处理程序代码
mythread->SuspendThread();
}
恢复线程使用ResumeThread()函数,在恢复线程按钮中添加代码:
void CSingleThreadDlg::OnBnClickedresumethread()
{
// TODO: 在此添加控件通知处理程序代码
mythread->ResumeThread();
}
为了测试多线程是否有效,在跳出弹窗按钮中添加代码,使其跳出一个弹窗:
void CSingleThreadDlg::OnBnClickedDialog()
{
// TODO: 在此添加控件通知处理程序代码
MessageBox(_T("正常!"));
}
实际测试中,点击计算,查看任务管理器,CPU使用率会暴涨,此时可以正常点击跳出弹窗按钮。当点击暂停线程按钮,CPU使用率恢复正常,当点击恢复线程按钮,CPU使用率再次暴涨。