线程的CloseHandle和WaitForSingleObject
最近在学习的时候 需要创建多线程的应用程序来访问设备 但是不知道为什么始终进不了线程的执行函数里边 经过一番百度 知道了原因 写下以下总结
在学习线程的时候书上有这么一段话“线程对象也可以提前释放,对于大部分的句柄来说,使用CloseHandle函数关闭句柄意味着整个对象被释放,但对于线程句柄来说,关闭它仅释放线程的统计信息,并不会终止线程的执行,如果不在需要使用线程句柄的话,在调用CreateThread后马上就可以将它关闭掉,线程的执行并不会受影响”
以下是一段测试代码:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hStdOut dd ?
hThread dd ?
.const
szShow db '进入了线程执行函数',0dh,0ah,0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Thread proc uses ebx esi edi,_lParam
invoke lstrlen,offset szShow
push ecx
invoke WriteConsole,hStdOut,offset szShow,eax,esp,NULL
pop ecx
ret
_Thread endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke GetStdHandle,STD_OUTPUT_HANDLE
mov hStdOut,eax
push ecx
invoke CreateThread,NULL,0,offset _Thread,NULL,0,esp
pop ecx
mov hThread,eax
invoke CloseHandle,hThread
invoke WaitForSingleObject,hThread,INFINITE;
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
在上面的代码中,创建完线程以后,就把线程句柄关闭了 但是并没有像预期的那样打印出“进入了线程执行函数” 是没有进入_Thread吗? 还是其他什么原因了
用OllyDBG跟入发现
第一 在_Thread中设置了断点 但是没有断下来就结束了
第二 WaitForSingleObject函数返回失败
百度以后发现一下内容
1. 对于内核对象,系统会维护一个引用计数,
2. 对于每个进程,进程本身维护了一个句柄表,记录它可以操作的内核对象在本进程内的映射值(就是句柄)
3. CloseHandle会删除内核对象的一个引用计数,同时会删除进程句柄表中的一项(如果该句柄在进程内再无引用)
4. WaitForSingleObject对传进来的句柄首先执行的动作就是查进程的句柄表,如果不存在这一项,返回无效句柄错误
WaitForSingleObject在CloseHandle前调用,这个使用hThread还在进程句柄表里
CloseHandle先一步把进程句柄表里的hThread这一项删掉了,再去WaitForSingleObject当然找不到句柄了
修改上边的程序 把WaitForSingleObject放在CloseHandle前执行
......
invoke WaitForSingleObject,hThread,INFINITE;
invoke CloseHandle,hThread
......
程序打印出了 期待的“进入了线程执行函数”
由此可以总结 以后在使用CloseHandle关闭线程句柄时 要确认是否后边还要用到它 是否查询进程的句柄表
线程的CloseHandle和WaitForSingleObject相关推荐
- wince -- 线程中SetEvent及WaitForSingleObject用法
设置事件的状态为有标记,释放任意等待线程.如果事件是手工的,此事件将保持有标记直到调用ResetEvent.这种情况下将释放多个线程,如果事件是自动的,此事件将保持有标记,直到一个线程被释放,系统将设 ...
- MFC 多线程及线程同步
一.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消息机制,通常 ...
- VC++中线程同步技术分析3
管理事件内核对象 在前面讲述线程通信时曾使用过事件内核对象来进行线程间的通信,除此之外,事件内核对象也可以通过通知操作的方式来保持线程的同步.对于前面那段使用临界区保持线程同步的代码可用事件对象的线程 ...
- 线程同步机制有临界区、互斥、信号量优缺点
线程同步技术. 1. Critical Sections(临界段),源代码中如果有不能由两个或两个以上线程同时执行的部分,可以用临界段来使这部分的代码执行串行化.它只能在一个独立的进程或一个独立的应用 ...
- Visual C++线程同步技术
线程同步的方式有: 临界区 管理事件内核对象 信号量内核对象 互斥内核对象 分别介绍如下: 使线程同步 在程序中使用多线程时,一般很少有多个线程能在其生命期内进行完全独立的操作.更多的情况是一些线程进 ...
- 【详解】消息队列和线程关系
1.进程-线程-消息队列 简单的来说,什么是进程?什么是线程?打个比方,你的程序要执行,操作系统就会把你的exe文件加载到内存中,那就生成一个进程了(当然还包含分配到的资源等):对于线程,你可以理解成 ...
- 如何正确的关闭 MFC 线程
前言: 近日在网上看到很多人问及如何关闭一下线程,但是我看网上给出的并不详细,而且有些方法还是错误的.小弟在此拙作一篇,不谈别的,只谈及如何正确的关闭MFC的线程,至于Win32和C RunTime的 ...
- 经典线程同步 事件Event
Event 内核对象,实际上是解决线程同步问题的利器. 介绍下函数应用: 第一个 CreateEvent 函数功能:创建事件 函数原型: HANDLECreateEvent( LPSECURITY_A ...
- java 线程亲缘性_第7章 线程调度、优先级和亲缘性(1)
7.1线程的挂起和恢复 (1)线程挂起 ①创建时(如CreateProcess.CreateThread),传入CREATE_SUSPENDED标志 ②用SuspendThread挂起线程.这个函数可 ...
最新文章
- [C# 网络编程系列]专题四:自定义Web浏览器
- PMCAFF“音乐+社交”产品马拉松大赛圆满结束,10支队伍大放异彩
- leetcode 911. Online Election | 911. 在线选举(加强堆 + 二分查找)
- scss百分号操作符的一个使用例子
- 图解,C语言希尔排序
- Eureka缓存机制
- HTML判断如果并且,将html转换为js,并且其中含有判断语句
- 今天小暑是什么时间_来自小暑的问候,小暑黄鳝赛人参,这5种民俗食物别错过...
- Oracle odi 数据表导出到文件
- Android开机画面显示
- 2022金属非金属矿山(露天矿山)安全管理人员考试练习题模拟考试平台操作
- Codeforces 1006A
- 管理部门使用计算机属于固定资产核算吗,固定资产核算管理内容
- 利用Python解决掉谷歌人机验证,全自动识别真的牛啊
- Verilog实现序列信号发生器
- 微信登录界面的那个男孩,他每天影响着11.51亿人
- MQTT协议快速了解
- 手机信号弱或服务器维护,只需几步,即可解决手机信号弱的问题
- CIE LAB色差公式与 CIE DE 2000色差公式计算类
- 手游SDK相关业务知识