调用线程c 主函数调用头文件AfxBeginThreadc 主函数调用头文件要包含什么头文件

博客访问: 1305220
博文数量: 206
博客积分: 4227
博客等级: 上校
技术积分: 2789
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
AfxBeginThread && 用户界面线程和工作者线程都是由AfxBeginThread创建的。现在,考察该函数:MFC提供了两个重载版的AfxBeginThread,一个用于用户界面线程,另一个用于工作者线程,分别有如下的原型和过程:用户界面线程的AfxBeginThread 用户界面线程的AfxBeginThread的原型如下:CWinThread* AFXAPI AfxBeginThread(CRuntimeClass* pThreadClass,int nPriority, UINT nStackSize, DWORD dwCreateFlags,LPSECURITY_ATTRIBUTES lpSecurityAttrs)其中:参数1是从CWinThread派生的RUNTIME_CLASS类;参数2指定线程优先级,如果为0,则与创建该线程的线程相同;参数3指定线程的堆栈大小,如果为0,则与创建该线程的线程相同;参数4是一个创建标识,如果是CREATE_SUSPENDED,则在悬挂状态创建线程,在线程创建后线程挂起,否则线程在创建后开始线程的执行。参数5表示线程的安全属性,NT下有用。&工作者线程的AfxBeginThread 工作者线程的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分别指定线程的优先级、堆栈大小、创建标识、安全属性,含义同用户界面线程。&&附录A:&结束线程的两种方式&&&& 当你在后台用线程来打印一些图形时.有时在打印一部分后,你希望可以停下来,那么此如何让线程停止呢.下面会详细的向你解释要结束线程的两种方式&&&& 1 : 这是最简单的方式,也就是让线程函数执行完成,此时线程正常结束.它会返回一个值,一般0是成功结束,当然你可以定义自己的认为合适的值来代表线程成功执行.在线程内调用AfxEndThread将会直接结束线程,此时线程的一切资源都会被回收.&&&& 2 : 如果你想让别一个线程B来结束线程A,那么,你就需要在这两个线程中传递信息.不管是工作者线程还是界面线程,如果你想在线程结束后得到它的确结果,那么你可以调用&&&& ::GetExitCodeThread函数&&&还是老师的那个项目,以前由于计算量太大,导致程序经常出现假死的现象,因为程序只有一个线程,该线程主要用于处理计算上了,而对于消息队列的响应被忽略了。因此解决的办法就是用两个线程,一个线程用于计算,一个线程用于处理消息。&&&&& 到网上找了一些资料,发现在MFC中把线程分为两类,一类为界面线程,一类为工作线程。两者的区别在于前都能够处理消息响应,而后者则不能。对于该项目来说,只要把计算的过程放到一个工作线程里来进行就可以了。&&& 现在先试一下,我新建了一个对话框,上面添加两个按钮,一个是start 一个是dialog。前者用于开始计算,而后者则弹出一个消息框。然后向该对话框里面添加一个死循环的函数UINT CMultithreadDlg::jisuan(LPVOID lpParam){int i = 1;for (;;){&& i+=i;}return 0;}&&&
然后在start按钮的响应函数上添加上jisuan(NULL);即可,现在运行程序,按下start按钮后,可以看到CPU使用率涨到了100%,这
个时候再按dialog按钮无反应,拖动关闭窗口均无效。这就是前面提到的假死现象(实际上是真死,因为死循环了,如果不是死循环,而只是计算量太大才是
假死)。&&& 下面用多线程的方法来解决,在start按钮的响应函数改为CWinThread* mythread = AfxBeginThread(&& jisuan,&& NULL,&& THREAD_PRIORITY_NORMAL,&& 0,&& 0,&& NULL&& );&&&
运行,结果发现有错error C2665: 'AfxBeginThread' : none of the 2 overloads can
convert parameter 1 from type 'unsigned int (void *)' Generating Code...我就纳闷了,函数指针是对的啊,原来 线程函数可以且必须是全局函数或者是静态成员函数。所以我们在线程函数的声明中改为 static UINT jisuan(LPVOID lpParam);即可,然后运行程序,这时点击start,待CPU涨至100%后,点击dialog,弹出对话框了,拖动、关闭窗口均没问题了。&&&&
其实上面的那个AfxBeginThread,除前面两个参数外,后面的都是默认参数,可以省略。而必须有的这两个参数,一个是线程函数的指针,一个是传
递给这个函数的参数。实际中我们经常这样用
AfxBeginThread(ThreadProc,this);//把this传过去,就可以调用类的成员了.
这样线程函数就可以使用和操作类的成员了。千万要注意线程函数是静态类函数成员。&&& 线程是创建了,但是如果中途要暂停该怎么做呢?&&& 我们在创建线程的时候获得了一个CWinThread的指针,这是一个指向线程对象的指针,CWinThread类里面就有暂停与恢复的函数,下面我就演示一下。在原来的程序上进行改动。向对话框类里面添加一个CWinThread* 的成员变量,不用初始化为NULL,这样会报错的,因为它只能通过AfxBeginThread函数获得。把start里面的声明去掉。然后添加一个 pause 按钮向其响应函数里面添加代码 mythread-&SuspendThread();&& 再添加一个 resume按钮,向其响应函数里面添加 mythread-&ResumeThread();&&& 再运行程序,我们start之后,按下pause可以看到CPU恢复正常,然后resume,CPU又涨上去了,到此证明一切操作正常。
阅读(9826) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。多针线程afxBeginThread用法及参数传入
AfxBeginThread是MFC的全局函数,是对CreateThread的封装。
CreateThread是Win32 API函数,前者最终要调到后者。
具体说来,CreateThread这个 函数是windows提供给用户的 API函数,是SDK的标准形式,在使用的过
程中要考虑到进程的同步与互斥的关系,进程间的同步互斥等一系列会导致操作系统死锁的因素,用起来
比较繁琐一些,初学的人在用到的时候可能会产生不可预料的错误,建议多使用AfxBeginThread,是编译
器对原来的CreateThread函数的封装,用与MFC编程(当然,只要修改了项目属性,console和win32项目
都能调用)而_beginthread是C的运行库函数。
#include "stdafx.h"
int* pp=&m;
static UINT& ThreadFun(LPVOID pParam)
&for (i=0;i&10;i++)
&&cout&&i&&
&return 1;
static UINT& ThreadFun2(LPVOID pParam)
&&cout&&"m="&&&
*(int *)(pParam)&&
&&cout&&"*pp="&&*pp&&
&return 1;
int _tmain(int argc, _TCHAR* argv[])
&cout&&"main
Thread begin"&&
&AfxBeginThread(ThreadFun,NULL);
&AfxBeginThread(ThreadFun2, pp);
&Sleep(1000);
&cout&&"main Thread
&return 0;
DWORD& WINAPI&
SockUDP::RecvThread(LPVOID lparam)
& 正确:int sock=
*(int*)(lparam);
& 错误:int
sock=(int)(*lparam);
在MSDN中键入LPVOID,再查看Windows Data Type:
LPVOID Pointer to any type. This type is declared in WinDef.h as
typedef void *LPVOID;
也就明白了为什么不能直接用*LPVOID,要先转换为指针(int *)(LPVOID),再转换为
*(int*)(LPVOID)这样子就转换为整形变量了
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。14078人阅读
2.4 线程/图形学(9)
工作线程通常用来执行一些后台任务,如:数据计算、后台杀毒等等。因为不需要创建窗口和处理用户消息,编写比较容易,在程序中只要调用AfxBeginThread
函数就可以创建并启动一个工作线程了。
AfxBeginThread
的原型如下:
CWinThread&*AfxBeginThread(&
&&&&AFX_THREADPROC&pfnThreadProc,&&&&&&&&&&&&&&& & & & & && //指向控制函数的地址&
&&&&LPVOID&pParam,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& & & & & && //指向传递给控制函数的参数&
&nPriority&/*&=&THREAD_PRIORITY_NORMAL&*/
,& && //指定线程的优先级&
&&&&UINT&nStackSize&/*&=&0&*/
,&&&&&&&&&&&&&&&&&&&&&& & & & & &&& && //指定堆栈大小&
&&&&DWORD&dwCreateFlags&/*&=&0&*/
,&&&&&&&&&&&&& & & & & & & & //创建标识&
&&&&LPSECURITY_ATTRIBUTES&lpSecurityAttrs&/*&=&NULL&*/
&&&&//安全属性&
从上面参数可以看到,只有前两个参数是必须的,其余参数都使用默认的话,就可创建了一个具有普通优先级别的线程。
示例:编写一个应用程序,当在程序窗口按下鼠标左键,启动一个线程,该线程可以在屏幕上显示一个信息框。
1.新建单文档程序;
2.在视图类CPP文件添加一个准备作为线程的函数:
UINT&MessageThread(LPVOID&pParam)&
&&&&LPTSTR&&&&pMessage&=&(LPTSTR)pP&
&&&&CWnd&*pMainWnd&=&AfxGetMainWnd();&
&&&&::MessageBox(pMainWnd-&m_hWnd,&pMessage,&_T(&Thread&Message&
),&MB_OK);&
&&&&return
3.在视图类的鼠标左键消息响应函数中创建和启动线程:
&CThreadTestView::OnLButtonDown(UINT&nFlags,&CPoint&point)&
&&&&AfxBeginThread(MessageThread,&_T(&Greetings&from&your&thread!&
&&&&CView::OnLButtonDown(nFlags,&point);&
程序运行结果:
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3360883次
积分:34971
积分:34971
排名:第138名
原创:397篇
转载:88篇
评论:3403条
联系方式:
(1)(1)(1)(1)(1)(1)(2)(1)(1)(1)(1)(1)(1)(1)(1)(1)(3)(1)(1)(1)(1)(1)(1)(1)(2)(1)(1)(1)(1)(1)(3)(1)(1)(1)(1)(2)(1)(3)(3)(3)(1)(1)(3)(1)(1)(8)(1)(3)(2)(2)(3)(2)(3)(2)(1)(1)(2)(3)(6)(1)(4)(3)(1)(3)(5)(5)(5)(5)(1)(3)(5)(4)(4)(4)(5)(5)(1)(13)(11)(7)(5)(2)(5)(4)(5)(2)(7)(14)(18)(23)(19)(5)(35)(22)(21)(8)(10)(42)(49)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2016年2月 C/C++大版内专家分月排行榜第三2016年1月 C/C++大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。}

我要回帖

更多关于 线程怎么调用函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信