CWinThread类,以及和createthread API的区别
- 博客分类:
- 技术杂绘
CWinThread类,以及和createthread API的区别
2010年10月19日
CWinThread
CObject
└CCmdTarget
└CWinThread
CWinThread对象代表在一个应用程序内运行的线程。运行的主线程通常由CWinApp的派生类提供;CWinApp由CWinThread派生。另外,CWinThread对象允许一给定的应用程序拥有多个线程。
CWinThread支持两种线程类型:工作者线程(Worker Thread)和用户界面线程(UI thread)。工作者线程没有收发消息的功能(没有消息队列):例如,在电子表格应用程序中进行后台计算的线程。
用户界面线程具有收发消息的功能,并处理从系统收到的消息。CWinApp及其派生类是用户界面线程的例子。其它用户界面线程也可由CWinThread直接派生。
CWinThread类的对象存在于线程的生存期。如果你希望改变这个特性,将m_bAutoDelete设为FALSE。
要使你的代码和MFC是完全线程安全的,CWinThread类是完全必要的。框架使用的用来维护与线程相关的信息的线程局部数据由CWinThread对象管理。由于依赖CWinThread来处理线程局部数据(Thread Local Storage),任何使用MFC的线程必须由MFC创建。例如,由运行时函数_beginthreadex创建的线程不能使用任何MFC API。
为了创建一个线程,调用AfxBeginThread函数。根据你需要工作者线程还是用户界面线程,有两种调用AfxBeginThread的格式。如果你需要用户界面线程,则将指向你的CWinThread派生类的CRuntimeClass的指针传递给AfxBeginThread。如果你需要创建工作者线程,则将指向控制函数的指针和控制函数的参数传递给AfxBeginThread。对于工作者线程和用户界面线程,你可以指定可选的参数来修改优先级,堆栈大小,创建标志和安全属性。
AfxBeginThread线程将返回指向新的CWinThread对象的指针。
与调用AfxBeginThread相反,你可以构造一个CWinThread派生类的对象,然后调用CreateThread。如果你需要在连续创建和终止线程的执行之间重复使用CWinThread对象,这种两步构造方法非常有用。
CWinThread类成员
数据成员
m_bAutoDelete 指定线程结束时是否要销毁对象
m_hThread 当前线程的句柄
m_nThreadID 当前线程的ID
m_pMainWnd 保存指向应用程序的主窗口的指针
m_pActiveWnd 指向容器应用程序的主窗口,当一个OLE服务器被现场激活时
构造函数
CWinThread 构造一个CWinThread对象
CreateThread 开始一个CWinThread对象的执行
操作
GetMainWnd 查询指向线程主窗口的指针
GetThreadPriority 获取当前线程的优先级
PostThreadMessage 向另外的CWinThread对象传递一条消息
ResumeThread 减少一个线程的挂起计数
SetThreadPriority 设置当前线程的优先级
SuspendThread 增加一个线程的挂起计数
可重载函数
ExitInstance 重载以进行线程终止时的清理工作
InitInstance 重载以实现线程实例的初始化
OnIdle 重载以进行线程特定的空闲操作
PreTranslateMessage 在消息被发送到Windows函数TranslateMessage和DispatchMessage之前过滤消息
IsIdleMessage 检测特定的消息
ProcessWndProcException 截获线程消息和命令处理函数出现的所有未处理的异常
ProcessMessageFilter 在特定的消息到达应用程序之前截获消息
Run 线程的具有消息收发功能的控制函数,可重载以定制缺省的消息循环 具体说来,CreateThread这个 函数是windows提供给用户的 API函数,是SDK的标准形式.
AfxBeginThread,是编译器对原来的CreateThread函数的封装,用与MFC.
而_beginthread是C的运行库函数。
在使用AfxBeginThread时,线程函数的定义为:UINT _yourThreadFun(LPVOID pParam)
在使用CreateThread时,线程的函数定义为: DWORD WINAPI _yourThreadFun(LPVOID pParameter)。
两个的实质都是一样的,不过AfxBeginThread返回一个CWinThread的指针,就是说他会new一个CWinThread对象,而且这个对象是自动删除的(在线程运行结束时),给我们带来的不便就是无法获得它的状态,因为随时都有可能这个指针指向的是一个已经无效的内存区域,所以使用时(如果需要了解它的运行状况的话)首先CREATE_SUSPENDED让他挂起,然后m_bAutoDelete=FALSE,接着才ResumeThread,最后不要了delete那个指针。
CreatThread就方便多了,它返回的是一个句柄,如果你不使用CloseHandle的话就可以通过他安全的了解线程状态,最后不要的时候CloseHandle,Windows才会释放资源(线程内核对象).
下面我们就来看一下AfxBeginThread函数的内部实现
//启动worker线程
CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,
int nPriority, UINT nStackSize, DWORD dwCreateFlags,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{
ASSERT(pfnThreadProc != NULL);
CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);
ASSERT_VALID(pThread);
if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPEN DED, nStackSize,
lpSecurityAttrs))
{
pThread->Delete();
return NULL;
}
VERIFY(pThread->SetThreadPriority(nPriority));
if (!(dwCreateFlags & CREATE_SUSPENDED))
VERIFY(pThread->ResumeThread() != (DWORD)-1);
return pThread;
}
//启动UI线程
CWinThread* AFXAPI AfxBeginThread(CRuntimeClass* pThreadClass,
int nPriority, UINT nStackSize, DWORD dwCreateFlags,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{
ASSERT(pThreadClass != NULL);
ASSERT(pThreadClass->IsDerivedFrom(RUNTIME_CLASS(CW inThread)));
CWinThread* pThread = (CWinThread*)pThreadClass->CreateObject();
if (pThread == NULL)
AfxThrowMemoryException();
ASSERT_VALID(pThread);
pThread->m_pThreadParams = NULL;
if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPEN DED, nStackSize,
lpSecurityAttrs))
{
pThread->Delete();
return NULL;
}
VERIFY(pThread->SetThreadPriority(nPriority));
if (!(dwCreateFlags & CREATE_SUSPENDED))
VERIFY(pThread->ResumeThread() != (DWORD)-1);
return pThread;
} 主要创建函数是 pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDE D, nStackSize,
lpSecurityAttrs))
也就是CWinThread::CreateThread.
发表评论
-
《Windows 核心编程》 -- 内核对象 --札记
2012-01-20 10:13 968《Windows 核心编程》 -- 内核对象 --札记 20 ... -
SDK网络连接/多线程示例代码
2012-01-20 10:13 692SDK网络连接/多线程示例代码 2010年06月09日 ... -
多线程编程(一)――CreateThread
2012-01-20 10:13 976多线程编程(一)――Creat ... -
FCKEditor 2.6.4 Asp.net上传文件没有权限解决
2012-01-20 10:13 767FCKEditor 2.6.4 Asp.net上传文件没有权限 ... -
Flash务实主义(四)――Flash中的MVC
2012-01-19 15:13 622Flash务实主义(四)――Flash中的MVC 2011年 ... -
只学一点点:我的技术学习策略
2012-01-19 15:13 636只学一点点:我的技术学 ... -
Flash Flex 国际化问题解决方案大全
2012-01-19 15:13 1091Flash Flex 国际化问题解 ... -
flex 问题
2012-01-19 15:13 600flex 问题 2011年04月04日 ... -
一名优秀的Flex开发者需要知道的10样东西
2012-01-19 15:13 587一名优秀的Flex开发者需要知道的10样东西 2010年06 ... -
最全的文件扩展名大全(二)
2012-01-17 05:00 868最全的文件扩展名大全(二) 2010年11月13日 PD ... -
DirectUI 的初步分析
2012-01-17 05:00 872DirectUI 的初步分析 2011年05月04日 D ... -
什么软件支持什么格式
2012-01-17 05:00 809什么软件支持什么格式 ... -
eclipse工具使用技巧&关联Android源码
2012-01-17 05:00 853eclipse工具使用技巧&关联Android源码 ... -
FMS客户端ActionScript 语言的参考
2012-01-16 03:51 741FMS客户端ActionScript 语言 ... -
Learning Flash Media Server 3中文版-第4章之2/6
2012-01-16 03:51 661Learning Flash Media Server 3 ... -
fms远程共享对象
2012-01-16 03:51 719fms远程共享对象 2011年0 ... -
FMS/red5客户端信息对象
2012-01-16 03:51 1332FMS/red5客户端信息对象 2010年11月16日 ... -
FMS_api
2012-01-16 03:51 726FMS_api 2010年03月11日 //====== ...
相关推荐
主要介绍了VC中CWinThread类以及和createthread API的区别分析,较为详细的讲述了CWinThread类的原理,并以实例形式对AfxBeginThread函数的内部实现进行了解释说明,需要的朋友可以参考下
这是一个关于CWinThread以及利用继承自CWinThread使用多线程的程序! 1,尽量使用DECLARE_DYNCREATE,这样能够动态创建。 2,继承自CWinThread,所以可以使用CreateThread()函数进行线程创建,在最开始我被书...
cwinthread的具体实现,窗口线程类
MFC的CWinThread线程有两种,一种称为Work线程,一种称为UI线程。一般情况下Work线程与UI线程的区别主要在于UI线程有消息队列(并不是有没有界面,这点要注意,UI线程也是可以没有界面的)
线程间要处理好同步与通讯,如果用CWinThread好一点,直接是一个线程对象,如果用AfxBeginThread,那必须定个全局函数,或者写个静态函数,一般是传个this指针进去,然后再用这个指针调用本类函数的成员函数,...
上位机的串口通信例子,定时发送接收都没问题。 使用CWinthread实现多线程发送和接收。 刚接触MFC多线程学习的新手会进一步理解多线程。
该程序的功能为利用MFC的多线程类CWinThread实现多线程文件复制。
在InitInstance()函数中,创建了一个单文档模板类或多文档模板类(CDocTemplate)的对象,并且在文档模板的构造函数中,系统定义的宏RUNTIME_CLASS创建了文档类对象,框架窗口类对象和视图类对象. 在MFC应用程序中有且仅有...
第二种是启动多线程,不同模式下启动函数不同,mfc与API与WIN32下面注意点也是有区别的! VC启动一个新线程的三种方法,有需要的朋友可以参考下。 第一种AfxBeginThread() 用AfxBeginThread()函数来创建一个新...
如果用CWinThread好一点,直接是一个线程对象,如果用AfxBeginThread,实现了这个类,来所简化多线程的创建和关闭的操作。
获得应用程序主窗口的指针 主窗口指着保存在CWinThread::m_pMainWnd
mfc非文档单FormView的使用,C++thunk for 32/64位,CWinThread无GUI工作线程,无GUI定时器,WINAPI调用方式的C++类封装。
在InitInstance()函数中,创建了一个单文档模板类或多文档模板类(CDocTemplate)的对象,并且在文档模板的构造函数中,系统定义的宏RUNTIME_CLASS创建了文档类对象,框架窗口类对象和视图类对象. 在MFC应用程序中有且仅有...
实现方法: 用MFC的程序向导生成一个常规DLL,在常规DLL内有一派生自CWinApp的实例,再用MFC的程序向导生成一个MFC EXE应用程序,把MFC EXE应用程序中 CAppView,CMainFrame,CAppDocument的文挡和RES目录下的资源拷贝到...
CWinApp 应用程序类共63个成员,文档全面的叙述各个成员
3.4 设计线程类——CWinThread 3.5 【实例】多线程文件搜索器 第4章 Windows图形界面 4.1 了解窗口 4.2 第一个窗口程序 . 4.3 一个“简陋”的打字程序 4.4 GDI基本图形 4.5 ...
Simple Multithreaded Application in pure C, Win32 and MFC. using Synchronization: 1. no Synchronization 2. Critical Section Objects 3. Mutex 4. Event ALL sample code write with VC6.0, simplicity!...
参数1是从CWinThread派生的RUNTIME_CLASS类; 参数2指定线程优先级,如果为0,则与创建该线程的线程相同; 参数3指定线程的堆栈大小,如果为0,则与创建该线程的线程相同; 参数4是一个创建标识,如果是CREATE_...