博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Win32多线程之核心对象
阅读量:4682 次
发布时间:2019-06-09

本文共 2056 字,大约阅读时间需要 6 分钟。

  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,那么这个进程可能最终有数百甚至数千个开启的“线程核心对象”留给操作系统去清理,这样的资源泄漏可能会对效率带来负面的影响。
      你不可以依赖“因线程的结束而清理所有被这一线程产生的核心对象”。虚度对象,例如文件,是被进程所拥有,而非被线程拥有。在进程结束之前不能够清理它们。

转载于:https://www.cnblogs.com/rainbow70626/p/8094178.html

你可能感兴趣的文章
cdn连接失败是什么意思_关于CDN的原理、术语和应用场景那些事
查看>>
ultraedit26 运行的是试用模式_免费试用U盘数据恢复工具 – 轻松找回U盘丢失的各种数据!...
查看>>
plsql 查询存储过程死锁语句_插入语句/存储过程死锁
查看>>
bootstrap table 收缩_bootstrap-table方法之:expandRow-collapseRow,展开或关闭当前行数据...
查看>>
jsp跳转到本身页面_五种JSP页面跳转方法详解
查看>>
mysql r_mysql:’r’是什么意思?
查看>>
无法加载 mysql 扩展_请检查您的 php 配置. - 文档_无法载入 mysql 扩展 请检查 PHP 配置...
查看>>
非空 默认 男 mysql_MySQL进阶13--常见六大约束: 非空/默认/主键/唯一约束/检查约束/外键约束--表级约束 / 列级约束...
查看>>
mysql错误修改数据_mysql数据修改问题
查看>>
navicat忘记mysql密码_navicat连接My SQL时忘记root密码处理方法
查看>>
mysql 左连接 左外连接吗_什么是左外连接?左外连接在工作表查询中的应用
查看>>
python sum函数导入list_python sum函数iterable参数为二维list,start参数为“[]”该如何理解...
查看>>
docker 删除多余镜像_多余Basedisk删除和vDisk镜像反转技术简介
查看>>
mysqlin会使用索引吗_被面试官虐了,索引为何使用B+树,你知道吗
查看>>
mysql8单节点500m_Kubernetes 部署 Mysql 8.0 数据库(单节点)
查看>>
mysql数据工厂生产_MySQL超时与天蓝色数据工厂副本
查看>>
python缩进可以用在任何语句之后_每天一道Python选择题--python缩进
查看>>
mysql查询左边大于左边_MySQL WHERE 子句
查看>>
java 获取颜色_java关于照片属性的获取,颜色模式
查看>>
CentOS7.5删除旧的内核
查看>>