内核对象的使用计数是由内核管理的,当一个进程结束访问这个内核对象时,计数器就增一,这个进程结束时,计数器就减一,当为0时就销毁。这个是自动管理的。孙鑫老师的教程里刚创建完一个线程,接着就调用CloseHandle函数,这是什么意思?刚创建的时候线程内核对象的计数器不是1吗?那给他减一以后不成了0了?那不是销毁了吗?
“在CloseHandle返回之前,会清除进程句柄表中的表项,不论系统内核是否已经被销毁,都会发生清除操作。当调用CloseHandle函数之后,将不在有对内核对象的访问权”,这会给程序带来那些影响?谁举几个直观点的例子还有,书上在对内核对象的介绍里,说的是“当一个进程结束访问这个内核对象时,计数器就增一,这个进程结束时,计数器就减一”,对于线程内核对象来说,就应该是“当一个线程结束访问这个内核对象时,计数器就增一,这个线程结束时,计数器就减一”了吧?是这样的吗?于是乎,又有一个新的问题产生了,进程对象、线程对象都是内核对象。既然内核对象归系统内核管理,而不是进程。多个进程可以引用一个对象。那CreateProccess时“将创建一个进程内核对象,并将这个对象的初始使用计数设置为1”这句话又是怎么回事?刚才说的线程也是亦然
“在CloseHandle返回之前,会清除进程句柄表中的表项,不论系统内核是否已经被销毁,都会发生清除操作。当调用CloseHandle函数之后,将不在有对内核对象的访问权”,这会给程序带来那些影响?谁举几个直观点的例子还有,书上在对内核对象的介绍里,说的是“当一个进程结束访问这个内核对象时,计数器就增一,这个进程结束时,计数器就减一”,对于线程内核对象来说,就应该是“当一个线程结束访问这个内核对象时,计数器就增一,这个线程结束时,计数器就减一”了吧?是这样的吗?于是乎,又有一个新的问题产生了,进程对象、线程对象都是内核对象。既然内核对象归系统内核管理,而不是进程。多个进程可以引用一个对象。那CreateProccess时“将创建一个进程内核对象,并将这个对象的初始使用计数设置为1”这句话又是怎么回事?刚才说的线程也是亦然
1,你刚创建一个线程,这个内核线程对象hThread就初始化为1,然后你CloseHandle(),则这个hThread的线程计数就变为0,内核就会销毁这个hThread,从此刻开始,你在也不能对这个句柄hThread操作了,因为已经销毁了。但运行的线程还依然存在,直至线程自己退出,你在也不能像这样Kill(hThread)这样的方式来结束这个线程,因为hTread句柄已经被销毁了,是无效的了
你把CreateThread返回值关闭后指针计数为2,句柄计数为1,因为csrss还有一份线程句柄如果仅用NtCreateThread创建线程而不通知csrss,线程的指针计数为2,句柄计数为1
你把这个句柄关了后指针计数为1,句柄计数为0
线程结束后这两个计数不一定减为0,因为可能还有东西正在使用这个对象
进程的句柄计数类似,但是指针计数会更大
CreateProccess“将创建一个进程内核对象,并将这个对象的初始使用计数设置为1” 请问如果不是设为1 那应该是几? closehandle只会使计数器减一,数如果大于1的话,在销毁这个内核对象时 你要调用几个closehandle?
CreateProccess创建的进程的句柄计数至少是2把对象的所有句柄都关了也不一定会销毁对象,因为还可能有指针计数
内核对象刚被创建时,ObpAllocateObject将其指针计数设置为1
操作系统来管理并调度其运行的,当_beginThreadex
成功后操作系统会在内核中生成一个线程内核对象,同时
置其引用计数为1,然后将该内核对象的指针挂入所属
进程的内核对象句柄表中,形成API可以访问的句柄资源,
因此其引用计数+1,变成了2,进程调用CloseHandle()
是关闭了该句柄的访问属性,并使其引用计数-1,由于线程
正在运行中,没有结束,因此该线程内核对象的引用计数还剩
1,当线程结束后(由操作系统调度程序发现),其引用计数会被
操作系统调度程序自动-1,变成0后在内核中就会被销毁了。其实就和c/c++中的动态分配内存,使用完毕后手工释放的道理一样,
只不过内核对象的指针变成句柄,可能会被多次引用\复制(DuplicateHandle),
操作系统使用引用计数来控制其生命周期。
线程(OpenThread(...))同样会增加其引用计数,
此时操作系统会把该线程内核对象的指针挂入进程
的句柄表中(虽然线程不属于我,可我一样能够占用),
所以即使线程所属的进程退出了,但该线程内核对象
的引用计数是1,还存在着,但由于其已经停止运行,
因此不占用CPU,当该进程结束后,操作系统会将进程
内核对象句柄表中的所有句柄调用CloseHandle(),减少
其引用计数。这也是为何内核对象不会导致操作系统资源泄漏
的原因。
你的理解完全错误,如果内核销毁了这个hThread,那该线程如何被
调度使用CPU时间片?如何在被调度的时候使用THREADCONTEXT进行
现场保存和切换?