采用CreateThread()创建多线程程序 MFC |
您所在的位置:网站首页 › 创建线程createthread › 采用CreateThread()创建多线程程序 MFC |
采用CreateThread()创建多线程程序
在window环境下,Win32 提供了一系列的API函数来完成线程的创建、挂起、恢复、终结以及通信等工作: 1、主要的函数列表:序号 函数名 功能 1 CreateThread() 创建一个新线程 2 ExitThread() 正常结束一个线程的执行 3 TerminateThead() 强制终止一个线程的执行 4 ResumeThread() 重启一个线程 5 SuspendThread() 挂起一个线程 6 GetExiCodeThread() 得到一个线程的退出码 7 GetThreadPriority() 得到一个线程的优先级 8 SetThreadPriority() 设置一个线程的优先级 9 CloseHandle() 关闭一个线程的句柄 10 CreateRemoteThread() 再另一个进程中创建一个新线程 11 PostThreadMessage() 发送一条消息给指定的线程 12 GetCurrentThread() 得到当前的线程句柄 13 GetCurrentThreadId() 得到当前线程的ID 14 GetThreadId() 得到指定线程的ID 15 WaitForSingleObject() 等待单个对象 16 WaitForMultipleObjects() 等待多个对象 关于多线程的API函数还有很多,以上只是列出了一些比较常用的函数,欲知更多函数和函数的使用方法,请参考MSDN或网络资源,在此就不再介绍了。 2、线程函数的定义:线程函数的规范格式定义为 DWORD WINAPI ThreadProc (LPVOID lpParam);//格式不正确将无法调用成功。函数名称没有限制,只要符合命名规则就可以。 但我常常看到有下列的线程函数定义: void ThreadProc ();//该格式也是可以的,但使用的时候要这样通过 LPTHREAD_START_ROUTINE转换,如: (LPTHREAD_START_ROUTINE)ThreadProc 我建议还是使用规范的格式比较好,不推荐使用void ThreadProc ()格式。不信就请看看MSDN的说明吧: Do not declare this callback function with avoid return typeand cast the function pointer to LPTHREAD_START_ROUTINE when creatingthe thread. Code that does this is common, but it can crash on 64-bit Windows. 而且线程函数必须是全局函数,不能在类中声明和定义。 3、多线程实例1:我在此将写一个简单的多线程程序,用以展示多线程的功能和使用方法。该程序的主要的思想是画3个进度条,分别以多线程和单线程方式完成,大家可以比较一下。 说明: (1)该程序还将和单线程做对比。 (2)由于给线程的函数传递了多个参数,所以采用结构体的方式传递参数。 (3)为了演示效果,采用了比较耗时的打点处理。 主要的函数如下: 在头文件的定义 [cpp] view plain copy print ? //线程函数声明 DWORD WINAPI ThreadProc(LPVOIDlpParam); //为了传递多个参数,我采用结构体 struct threadInfo { HWND hWnd; //窗口句柄 int nOffset; //偏移量 COLORREF clrRGB; //颜色 }; protected: HANDLE hThead[3]; //用于存储线程句柄 DWORD dwThreadID[3];//用于存储线程的ID threadInfo Info[3]; //传递给线程处理函数的参数//实现文件中 [cpp] view plain copy print ? //单线程测试 void CMultiThread_1Dlg::OnBnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 //使能按钮 GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON2)->EnableWindow(FALSE); CDC *dc = GetDC(); CRect rt; GetClientRect(rt); dc->FillSolidRect(0,0,rt.Width(),rt.Height()-70,RGB(240,240,240));//刷新背景 dc->TextOut(97,470,"#1"); dc->TextOut(297,470,"#2"); dc->TextOut(497,470,"#3"); //#1 for (int i=0;iFillSolidRect(0,0,rt.Width(),rt.Height()-70,RGB(240,240,240));//刷新背景 dc->TextOut(97,470,"#1"); dc->TextOut(297,470,"#2"); dc->TextOut(497,470,"#3"); //初始化线程的参数 Info[0].hWnd = Info[1].hWnd = Info[2].hWnd = GetSafeHwnd(); Info[0].nOffset = 10;Info[1].nOffset = 210;Info[2].nOffset = 410; Info[0].clrRGB = RGB(255,0,0);Info[1].clrRGB= RGB(0,255,0);Info[2].clrRGB = RGB(0,0,255); //创建线程 for (int i = 0;ihWnd)->GetDC(); for (int i=0;inOffset;jnOffset+190;j++) { dc->SetPixel(j,460-i,Info->clrRGB); } } DeleteObject(dc); return 0; }运行效果: 单线程测试
多线程测试 工程源码下载地址: http://download.csdn.net/detail/cbnotes/4857152 欢迎大家修改和指正。 注意事项: (1)传递给线程执行函数的参数不能是局部变量,而且必须是参数的地址。如: Int nOffset = 10; CreateThread(NULL,0,ThreadProc,nOffset,0,&dwThreadID[i]);//错误 CreateThread(NULL,0,ThreadProc,&nOffset,0,&dwThreadID[i]);//错误 Int *pOffset = newint(10); CreateThread(NULL,0,ThreadProc,pOffset,0,&dwThreadID[i]);//正确 (2)线程执行函数必须是全局函数。 (3)请大家改改下面的程序,且解释下为什么? 这是我开始写程序遇到的一个问题, 改写上面的函数:只是将结构体中一个参数改为CDC指针,以便直接调用。 structthreadInfo { CDC * dc; //画布 int nOffset; //偏移量 COLORREFclrRGB; //颜色 }; //多线程测试 voidCMultiThread_1Dlg::OnBnClickedButton2() { // TODO:在此添加控件通知处理程序代码 CDC *dc =GetDC(); CRectrt; GetClientRect(rt); dc->FillSolidRect(0,0,rt.Width(),rt.Height()-70,RGB(240,240,240));//刷新背景 dc->TextOut(97,470,"#1"); dc->TextOut(297,470,"#2"); dc->TextOut(497,470,"#3"); //初始化线程的参数 Info[0].dc = Info[1]dc = Info[2].dc = dc; Info[0].nOffset = 10;Info[1].nOffset = 210;Info[2].nOffset = 410; Info[0].clrRGB =RGB(255,0,0);Info[1].clrRGB=RGB(0,255,0);Info[2].clrRGB =RGB(0,0,255); //创建线程 for (inti = 0;i threadInfo*Info = (threadInfo*)lpParam; for (inti=0;i Info->dc->SetPixel(j,460-i,Info->clrRGB); } } return 0; } 运行结果: 为什么会这样呢?我还没有找到答案,望大家能给我个解释,谢谢。 =========================================================== 4、多线程实例2:该实例将演示一个简单的多线程协同工作的例子,以供大家学习和参考。大致原理是:5个人开始比赛(比如赛跑),谁先完成比赛就结束,并统比赛时间和赢者。主线程用于界面的相关显示,5个线程模拟5个人的行为(赛跑),另外一个线程用于检测5个线程的运行情况,只要有人到达终点,比赛就结束并做相关的技术统计。 主要函数为:
MulitThread_2Dlg.h : 头文件 //声明线程处理函数 DWORDWINAPI ThreadProc1(LPVOIDlpParam); DWORDWINAPI ThreadProc2(LPVOIDlpParam); //为了传递多个参数,我采用结构体 structthreadInfo1 { HWNDhWnd; //窗口句柄 int nOffset; //偏移量 };
structthreadInfo2 { HWNDhWnd; //窗口句柄 HANDLE *phHandle; //偏移量 }; protected: long m_nTime;//时间 HANDLEm_hThead[5]; //用于存储线程句柄 HANDLEhThead; //用于存储线程句柄 DWORD m_dwThreadID[5];//用于存储线程的ID
threadInfo1Info1[5]; //传递给线程处理函数的参数 threadInfo2Info2;
// MulitThread_2Dlg.cpp : 实现文件 //更新时间:毫秒 voidCMulitThread_2Dlg::OnTimer(UINT_PTRnIDEvent) { // TODO:在此添加消息处理程序代码和/或调用默认值 m_nTime+=100;//毫秒为单位 CStringstr; str.Format("时间:%.1f秒",m_nTime/1000.0); GetDlgItem(IDC_STATIC2)->SetWindowText(str); CDialog::OnTimer(nIDEvent); }
//消息处理函数 LRESULTCMulitThread_2Dlg::OnGameOver(WPARAMwParam,LPARAMlParam) { KillTimer(1);//关闭计时器 if (wParam ==0) {//出错 GetDlgItem(IDC_STATIC1)->SetWindowText("出错啦!"); GetDlgItem(IDC_STATIC2)->SetWindowText("---"); AfxMessageBox("出错啦!",MB_OK|MB_ICONERROR); } else {//成功 //显示结果 char *pName[] = {"张三","李四","王二","小蔡","赵干"}; CStringstr; str.Format("赢者:%s",pName[lParam]); GetDlgItem(IDC_STATIC1)->SetWindowText(str); } //使能开始按钮,以便可以开始下一次比赛 GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE); return 0; }
//开始比赛 voidCMulitThread_2Dlg::OnBnClickedButton1() { // TODO:在此添加控件通知处理程序代码 //使能开始按钮:无效 GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE); m_nTime =0;//初始化时间为 CDC *dc =GetDC(); CRectrt; GetClientRect(rt); dc->FillSolidRect(40,0,rt.Width()-49,rt.Height()-50,RGB(240,240,240));//刷新背景 ReleaseDC(dc); //初始化线程的参数 Info1[0].hWnd =Info1[1].hWnd =Info1[2].hWnd =Info1[3].hWnd =Info1[4].hWnd =GetSafeHwnd(); Info1[0].nOffset = 0;Info1[1].nOffset = 90;Info1[2].nOffset = 180;Info1[3].nOffset = 270;Info1[4].nOffset = 360; //创建线程 for (inti = 0;iSetWindowText("进行中..."); //开始运行 for (inti = 0;i for (intj=0;j threadInfo2*info = (threadInfo2*)lpParam; DWORDdwRet = 0; //等待个线程中的一个完成 dwRet =WaitForMultipleObjects(5,info->phHandle,FALSE,INFINITE); if (dwRet ==WAIT_FAILED) {//出错啦 ::SendMessage(info->hWnd,WM_GAMEOVER,0,0); return 0; } //终止各个线程 for (inti=0;i |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |