Win32多线程之核心对象
CreateThread()传回两个值,用以识别一个新的线程。第一个值是个Handle, 这也是CreateThread()的返回值,大部分与线程有关的API函数都需要它。第二个值是由lpThreadId带回来的线程ID。线程ID是一个全局变量,可以独一无二地表示系统中任一进程中的某个线程。AttachThreadInput()和PostThreadMessage()就需要用到线程ID,这两个函数允许你影响其他人(线程)的消息队列。调试器和进程观察器也需要 线程ID,为了安全防护的缘故,你不可能根据线程的ID而获得其handle。
CreateThread()传回来的handle被称为一个核心对象(kernal Object)。核心对象其实和所谓的GDI对象,如画笔,画刷或DC是差不多的,只不过它由Kernel.dll来管理,而画笔,画刷由GDI32.dll来管理。两种对象之间有许多相似性。
GDI对象是Windows的基础部分。在Win16或Win32中它们都是由操作系统管理。通常你不需要知道其数据格式。例如,你可能会调用SelectObject()或ReleaseObject()以处理GDI对象:Windows隐藏了实现细节,只是给你一个HDC或者一个HBRUSH,那都是对象的handle。
核心对象以HANDLE为使用时的参考依据,与GDI的HBRUSH,HPEN,HPALETTE以及其他handles不同的是,只有一种handle可以代表核心对象。所谓handle,其实是个指针,指向操作系统内存空间的某样东西,那东西不允许你直接取得。你的程序不能够直接取用它,为的是维护系统的完整性与安全性。
下面是各种Win32核心对象的清单。
1)进程(processes)
2)线程(threads)
3) 文件(files)
4)事件(events)
5)信号量(semaphores)
6)互斥器(mutexes)
7)管道(Pipes,分为named和anonymous两种)
其中事件,信号量,互斥器,这些核心对象可以用来整合许多的线程或进程。
注意:Critical Sections(临界区域、关键区域)并不是核心对象。
GDI对象和核心对象之间有一个主要的不同,GDI对象有单一拥有者,不是进程就是线程。核心对象可以有一个以上的拥有者,甚至可以跨进程。为了保持对每一位拥有者的追踪,核心对象保持了一个引用计数器,以记录有多少handles对应次对象,对象中也记录了那一个进程或线程是拥有者。如果你调用CreateThread()或是其它会传回handle的函数,引用计数便累加1.当你调用CloseHandle()时,引用计数便递减1.一旦引用计数降至0,这一核心对象即自动被摧毁。
面对一个打开的对象,区分其拥有者是进程或者是线程。是件很重要的事情。因为这回=会决定系统何时做清除善后(clean up)操作。所谓
clean up操作,包括将该进程或线程所拥有的每一个对象的引用计数减1,若有必要,则对象会被摧毁掉。程序员不能选择由进程或者线程拥有对象,一切得视对象类型而定。
由于引用计数的设计,对象有可能在产生该对象之进程结束之后还继续幸存。Win32提供各种机制,让其他进程得以取得一个核心对象的handle。如果某个进程握有某个核心对象的handle,而该对象的原创者(进程)已经“作古”了,次核心对象并不会被摧毁。
CloseHandle()的重要性
当你完成你的工作后,应该调用CloseHandle释放核心对象。
BOOL CloseHandle(HANDLE hObject);
参数
hObject 代表一个已打开之对象handle
返回值
如果成功,CloseHandle()返回TRUE,如果失败则传回FALSE.此时你可以调用GetLastError()获知失败原因。
如果一个进程没有在结束之前对它所打开的核心对象调用CloseHandle(),操作系统会自动把哪些对象的引用计数下降1.虽然你可以依赖系统做实体(physical)上的清除(cleanup)工作,然而逻辑上的清楚工作又是完全不同的一回事,特别是如果你有多个进程的话,因为系统并不知道对象实际代表什么意义,
所以它不可能知道解构顺序是否重要。
如果一个进程常常产生“worker 线程”而老是不关闭线程的handle,那么这个进程可能最终有数百甚至数千个开启的“线程核心对象”留给操作系统去清理,这样的资源泄漏可能会对效率带来负面的影响。
你不可以依赖“因线程的结束而清理所有被这一线程产生的核心对象”。虚度对象,例如文件,是被进程所拥有,而非被线程拥有。在进程结束之前不能够清理它们。
Win32多线程之核心对象的更多相关文章
- Java多线程编程核心 - 对象及变量的并发访问
1.什么是“线程安全”与“非线程安全”? “非线程安全”会在多个线程对同一对象总的实例变量进行并发访问时发生,产生的后果是“脏读”,也就是取到的数据其实是被更改过的. “线程安全”是以获得的实例变量的 ...
- 深入浅出Win32多线程程序设计之基本概念
一.深入浅出Win32多线程程序设计之基本概念[转] 引言 从单进程单线程到多进程多线程是操作系统发展的一种必然趋势,当年的DOS系统属于单任务操作系统,最优秀的程序员也只能通过驻留内存的方式实现所谓 ...
- 多线程学习:win32多线程编程基本概念(转)
一.定义: 1.进程和线程的区别 进程:是程序的执行过程,具有动态性,即运行的程序就叫进程,不运行就叫程序 ,每个进程包含一到多个线程.线程:系统中的最小执行单元,同一进程中有多个线程,线程可以共享资 ...
- Win32多线程编程(1) — 基础概念篇
内核对象的基本概念 Windows系统是非开源的,它提供给我们的接口是用户模式的,即User-Mode API.当我们调用某个API时,需要从用户模式切换到内核模式的I/O System Serv ...
- win32多线程-重写消息循环
最近正在学习<win32多线程程序设计>,这是其中一段重写消息循环的代码事例,以后可能用的上. while (!quit || gNumPrinting > 0) { // Wait ...
- Win32多线程编程(3) — 线程同步与通信
一.线程间数据通信 系统从进程的地址空间中分配内存给线程栈使用.新线程与创建它的线程在相同的进程上下文中运行.因此,新线程可以访问进程内核对象的所有句柄.进程中的所有内存以及同一个进程中其他所有线 ...
- Win32 多线程的创建方法和基本使用
Win32多线程的创建方法主要有: (1)CreateThread() (2)_beginthread()&&_beginthreadex() (3)AfxBeginThread() ...
- win32多线程程序设计笔记(第二章)
第二章线程的第一次接触,主要讲了如何创建线程以及需要注意的几点. 一.创建线程 与调用函数的过程类似;线程只不过用CreateThread的API将函数封装起来,并产生一个与主程序同时执行的程序来调用 ...
- win32多线程-异步过程调用(asynchronous Procedure Calls, APCs)
使用overlapped I/O并搭配event对象-----win32多线程-异步(asynchronous) I/O事例,会产生两个基础性问题. 第一个问题是,使用WaitForMultipleO ...
随机推荐
- 简单介绍aspose-words-18.10-jdk16做导出word
今天在搞那个用aspose words for java做导出word的功能,顺便简单介绍这个怎么用,我有两个版本的破解版,就都做简单介绍怎么用 警告:请勿用于商业用途,仅供学习研究使用,如有任何版权 ...
- Bean的自动装配及作用域
1.XML配置里的Bean自动装配 Spring IOC 容器可以自动装配 Bean,需要做的仅仅是在 <bean> 的 autowire 属性里指定自动装配的模式.自动装配方式有: by ...
- Mybatis之简单注解
Mybatis使用注解实现主键自增长: oracle: @SelectKey(statement="select my_seq.nextval from dual",resultT ...
- Struts2 数据校验之四兄弟
现在是科技的时代,大多数人都在网上购物了, 我们都碰到过相同的问题,各大网站弄的那些各种各样的注册页面,相信大家都深有体会. 有了这验证就很好的保证了我们的信息的准确性和安全性. 接下来我给大家讲解一 ...
- python中字符串格式化%与.format
Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...
- 有标号的DAG计数系列问题
传送门 II 设 \(f_i\) 表示 \(i\) 个点的答案 那么枚举至少 \(j\) 个点的出度为 \(0\) \[\sum_{j=0}^{i}(-1)^j\binom{i}{j}f_{i-j}2 ...
- <Android 基础(二十二)> EditText 无法显示完全以及尝鲜Android N
前言 最近将Android Studio更新到了2.2 ,模拟器的Android版本也来到了最新的Nougat.很令人兴奋的一件事情呢! 对, 我就是这么没出息.文章结尾来几张图. 问题 最近遇到一个 ...
- win10 程序crash后弹出 XXX已停止工作
需要attach调试器的时候弹出的"XXX已停止工作"很方便, 现在win10默认禁用掉了. 恢复的方法是: win+R 输入gpedit.msc回车 管理模板 -> Win ...
- weex 数据绑定,动态控制组件的显示内容及样式
无论的原生开发还是weex开发,经常会需要我们对一些组件/控件动态赋值,在原生中,我们大家都知道,对控件setText就可以了,那么在weex中呢,我们需要怎么做呢,其实很简单,几行代码就可以搞定!首 ...
- Java web相关内容
我们即将学习Java web 这是通过查阅资料找到的和Java web 相关的内容. 一:Java web的含义 JavaWeb,是用Java技术来解决相关web互联网领域的技术总和.web包括:we ...