1、 启动线程:

CWinThread* AfxBeginThread( 线程函数,this );

2、通常导致线程终止的两种情况是:控制函数退出或不允许线程完成运行。如果字处理器使用后台打印线程,若成功完成打印,则控制函数将正常终止。但是,如果用户要取消打印,后台打印线程则不得不提前终止。本主题介绍如何实现每一种情况,以及在终止后如何获取线程的退出代码。

(1)正常线程终止

对于辅助线程,正常线程终止很简单:退出控制函数并返回表示终止原因的值。可以使用 函数或 return 语句。一般情况下,0 表示成功完成,但这取决于您自己。

对于用户界面线程,该过程也很简单:从用户界面线程内调用 Platform SDK 中的 。PostQuitMessage 采用的唯一参数是线程的退出代码。对于辅助线程,0 通常表示成功完成。

(2)过早的线程终止

过早终止线程几乎一样简单:从线程内调用 。将所需的退出代码作为唯一参数传递。这将停止执行线程、解除对线程堆栈的分配、分离附加到线程的所有 DLL 并从内存中删除线程对象。

必须从要终止的线程内调用 AfxEndThread。如果要从其他线程终止线程,必须设置两个线程间的通信方法。

举一个例子:

可以创建一个信号量,用WaitForSingleObject函数来检测该信号量的状态。

成员变量 m_hThreadEvent;

m_hThreadEvent = CreateEvent( NULL, FALSE, FALSE, NULL );

线程的执行函数:

for( ; ;)
{
DWORD dwRetVal;
dwRetVal = WaitForSingleObject( m_hThreadEvent, );
if ( dwRetVal == WAIT_TIMEOUT )
{
// TODO:
}
else
{
// stop receive text thread.
DWORD dwExitCode;
GetExitCodeThread( m_pThreadRecv->m_hThread, &dwExitCode );
AfxEndThread( dwExitCode, TRUE );
}
}

要结束线程时,使用SetEvent,将信号量置为有信号。

该线程是在信号量有信号时,退出。

(3)TerminateThread

在CWinThread对象中有线程的句柄,可以使用该句柄强行杀死线程。但是不推荐使用这种方式,当可以正常结束的时候,选择前两种方法较好。

检索线程的退出代码

若要获取辅助线程或用户界面线程的退出代码,请调用 函数。有关此函数的信息,请参见 Platform SDK。此函数获取线程(存储在 CWinThread 对象的 m_hThread 数据成员中)的句柄和 DWORD 的地址。

如果线程仍然是活动的,GetExitCodeThread 将 STILL_ACTIVE 放置在提供的 DWORD 地址中;否则将退出代码放置在该地址中。

检索 对象的退出代码还需要一步。默认情况下,当 CWinThread 线程终止时,删除该线程对象。这意味着不能访问 m_hThread 数据成员,因为 CWinThread 对象不再存在。若要避免出现这种情况,请执行以下操作之一:

  • 将 m_bAutoDelete 数据成员设置为 FALSE。这使 CWinThread 对象在线程终止后仍可以继续存在。然后可以在线程终止后,访问 m_hThread 数据成员。但是,如果使用此方法,就得销毁 CWinThread 对象,因为框架不会自动删除该对象。这是首选方法。

  • 单独存储线程的句柄。创建线程后,(使用 ::DuplicateHandle)将其 m_hThread 数据成员复制到其他变量,并通过该变量访问该成员。这样,终止后即会自动删除对象,并且仍然可以找到线程终止的原因。请注意:在可以复制句柄之前,线程不终止。执行此操作的最安全的方式是将 CREATE_SUSPENDED 传递到 ,存储句柄,然后通过调用 继续执行线程。

任一方法都可以使您确定 CWinThread 对象终止的原因。

MFC启动和关闭线程的更多相关文章

  1. VC启动一个新线程的三种方法

    第一种AfxBeginThread() 用AfxBeginThread()函数来创建一个新线程来执行任务,工作者线程的AfxBeginThread的原型如下: CWinThread* AfxBegin ...

  2. MFC【17-1】线程和线程同步化

    17.1线程 对于Windows来说所有的线程都是一样的,但MFC却把线程区分为两种类型:User Interface(UI) threads(用户界面(UI)线程)和Worker threads(工 ...

  3. Golang控制goroutine的启动与关闭

    最近在用golang做项目的时候,使用到了goroutine.在golang中启动协程非常方便,只需要加一个go关键字: go myfunc(){ //do something }() 但是对于一些长 ...

  4. Jvm启动,关闭及对应钩子

    很多时候应用服务启动或关闭会做一些预加载(比如缓存,定时任务启动等)或收尾处理工作(比如程序失败记录等) 1. 首先看下Spring框架服务启动加载操作实现,直接上代码 继承实现接口Applicati ...

  5. ServletContextListener使用详解(监听Tomcat启动、关闭)

    在 Servlet API 中有一个 ServletContextListener 接口,它能够监听 ServletContext 对象的生命周期,实际上就是监听 Web 应用的生命周期. 当Serv ...

  6. Linux下Tomcat的启动、关闭

    在Linux系统下,启动和关闭Tomcat使用命令操作. 进入Tomcat下的bin目录 1 cd /java/tomcat/bin 启动Tomcat命令 1 ./startup.sh 停止Tomca ...

  7. Elasticsearch源码分析 | 单节点的启动和关闭

    本文主要简要介绍Elasticsearch单节点的启动和关闭流程.Elasticsearch版本:6.3.2 相关文章 1.Google Guice 快速入门 2.Elasticsearch 中的 G ...

  8. Oracle的启动与关闭

    启动数据库的前提条件: 环境变量定义好($ORACLE_HOME,$ORACLE_SID,$PATH) 能密码文件认证或OS认证(确保能登入sys) 有正确的参数文件(启动数据库需要查找参数文件,默认 ...

  9. MFC【17-3】线程和线程同步化

    17.3小知识点 17.3.1消息泵 编写一个应用程序,让它响应某菜单命令,画几千个椭圆. void CMFC线程View::OnStartDrawing(void) { m_bQuit=FALSE; ...

随机推荐

  1. HDU Count the string+Next数组测试函数

    链接:http://www.cnblogs.com/jackge/archive/2013/04/20/3032942.html 题意:给定一字符串,求它所有的前缀出现的次数的和.这题很纠结,一开始不 ...

  2. Linux命令(17)du 查看文件和目录磁盘使用情况

    Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的. 1.命令格式: du [选项][文件] 2.命令功能 ...

  3. contentprovider提供程序间共享数据的统一接口

    contentprovider提供程序间共享数据的统一接口

  4. Python基础10 反过头来看看

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 从最初的"Hello World",走到面向对象.该回过头来看 ...

  5. SQL锁表解决并发性

    在数据库开发过程中,不得不考虑并发性的问题,因为很有可能当别人正在更新表中记录时,你又从该表中读数据,那你读出来的数据有可能就不是你希望得到的数据.可以说有些数据同时只能有一个事物去更新,否则最终显示 ...

  6. 浅析JAVA_HOME,CLASSPATH和PATH的作用

    1,设置JAVA_HOME:  java的目录一.为了方便引用,比如,你JDK安装在C:\ProgramFiles\Java\jdk1.7.0目录里,则设置JAVA_HOME为该目录路径, 那么以后你 ...

  7. 把exe嵌入到自己的exe中。delphi xe3

    下面是一个把exe程序嵌入到我们自己的exe中.开发环境 Delphi XE3 Version 17.0.4625.53395.OS环境WIN7 SP1,由于xe3版本的引用库发生变化.换成其他版本的 ...

  8. 算法库:jpeglib和pnglib安装配置

    类似于OpenCV的安装配置.只不过OpenCV有编译好的,而jpeglib和pnglib需要自己编译.其实,若要跟踪OpenCV的源码或要使用OpenCV的扩展包,OpenCV也得自己编译. Ope ...

  9. Net文章汇总帖

    DevExpress:Data Grid ExamplesHow to: Initialize Cells in Newly Created RowsHow to: Set a Cell Value ...

  10. strstr、strcmp、strlen、strcpy

    const char* strstr(const char *str, const char* substr) { int i, j, temp; ; str[i] != '\0'; i++) { j ...