内核对象的使用计数是由内核管理的,当一个进程结束访问这个内核对象时,计数器就增一,这个进程结束时,计数器就减一,当为0时就销毁。这个是自动管理的。孙鑫老师的教程里刚创建完一个线程,接着就调用CloseHandle函数,这是什么意思?刚创建的时候线程内核对象的计数器不是1吗?那给他减一以后不成了0了?那不是销毁了吗?
“在CloseHandle返回之前,会清除进程句柄表中的表项,不论系统内核是否已经被销毁,都会发生清除操作。当调用CloseHandle函数之后,将不在有对内核对象的访问权”,这会给程序带来那些影响?谁举几个直观点的例子还有,书上在对内核对象的介绍里,说的是“当一个进程结束访问这个内核对象时,计数器就增一,这个进程结束时,计数器就减一”,对于线程内核对象来说,就应该是“当一个线程结束访问这个内核对象时,计数器就增一,这个线程结束时,计数器就减一”了吧?是这样的吗?于是乎,又有一个新的问题产生了,进程对象、线程对象都是内核对象。既然内核对象归系统内核管理,而不是进程。多个进程可以引用一个对象。那CreateProccess时“将创建一个进程内核对象,并将这个对象的初始使用计数设置为1”这句话又是怎么回事?刚才说的线程也是亦然

解决方案 »

  1.   

    CreateThread创建线程对象时,系统会设置该进程的内核对象为1,等Create完毕,会打开该进程的内核对象,使其计数器再加1…
      

  2.   

    你创建一个线程,就由内核创建一个线程句柄(内存块)来管理记录这个线程一些状态讯息。
    1,你刚创建一个线程,这个内核线程对象hThread就初始化为1,然后你CloseHandle(),则这个hThread的线程计数就变为0,内核就会销毁这个hThread,从此刻开始,你在也不能对这个句柄hThread操作了,因为已经销毁了。但运行的线程还依然存在,直至线程自己退出,你在也不能像这样Kill(hThread)这样的方式来结束这个线程,因为hTread句柄已经被销毁了,是无效的了
      

  3.   

    CloseHandle函数就是向系统表示你已经不再关心这个句柄了
      

  4.   

    你创建了线程(非SUSPEND)线程就会执行线程函数,此时closehandle,关闭了线程内核对象的句柄,但线程函数有可能还在执行,等执行完毕线程内核对象销毁,如果你不调用closehandle那么对象就不会销毁了
      

  5.   

    CreateThread()创建线程的时候,线程内核对象的引用计数为1,CreatThread返回的时候打开该内核对象,这个时候引用计数为2了。
      

  6.   

    CloseHandle 后 这个内核对象没了, 但是线程还在继续 直到线程退出!
      

  7.   

    用CreateThread刚创建出来的线程的指针计数为3,句柄计数为2
    你把CreateThread返回值关闭后指针计数为2,句柄计数为1,因为csrss还有一份线程句柄如果仅用NtCreateThread创建线程而不通知csrss,线程的指针计数为2,句柄计数为1
    你把这个句柄关了后指针计数为1,句柄计数为0
    线程结束后这两个计数不一定减为0,因为可能还有东西正在使用这个对象
    进程的句柄计数类似,但是指针计数会更大
      

  8.   

    内核对象可能会产生继承现象,如果继承的话,内核对象计数器会加1。
    CreateProccess“将创建一个进程内核对象,并将这个对象的初始使用计数设置为1” 请问如果不是设为1 那应该是几? closehandle只会使计数器减一,数如果大于1的话,在销毁这个内核对象时 你要调用几个closehandle?
      

  9.   

    windows核心编程 内核对象灰常详细  相信对LZ会有帮助
      

  10.   

    CreateProccess“将创建一个进程内核对象,并将这个对象的初始使用计数设置为1” 请问如果不是设为1 那应该是几?不要这么想当然,并且windows内核对象也没有使用计数这个说法,只有指针计数和句柄计数。指针计数不少于句柄计数
    CreateProccess创建的进程的句柄计数至少是2把对象的所有句柄都关了也不一定会销毁对象,因为还可能有指针计数
      

  11.   

    知道LZ上的是牛人 这里菜鸟冒昧的说一句 但是“使用计数”这个说法还是有的  而且正如LZ所说初次创建一个内核对象的时候 其使用计数会被置1
      

  12.   

    使用计数是个通用的说法,windows中由指针计数和句柄计数来具体实现。
    内核对象刚被创建时,ObpAllocateObject将其指针计数设置为1
      

  13.   

    你创建线程的那个线程也引用了被创建线程的内核对象。close表示说我创建后被创建的那个线程就与我无关了。
      

  14.   

    最近在看Windows 核心编程,感觉功力大增了,一起提高吧
      

  15.   

    线程在windows操作系统里其实是操作系统资源,由
    操作系统来管理并调度其运行的,当_beginThreadex
    成功后操作系统会在内核中生成一个线程内核对象,同时
    置其引用计数为1,然后将该内核对象的指针挂入所属
    进程的内核对象句柄表中,形成API可以访问的句柄资源,
    因此其引用计数+1,变成了2,进程调用CloseHandle()
    是关闭了该句柄的访问属性,并使其引用计数-1,由于线程
    正在运行中,没有结束,因此该线程内核对象的引用计数还剩
    1,当线程结束后(由操作系统调度程序发现),其引用计数会被
    操作系统调度程序自动-1,变成0后在内核中就会被销毁了。其实就和c/c++中的动态分配内存,使用完毕后手工释放的道理一样,
    只不过内核对象的指针变成句柄,可能会被多次引用\复制(DuplicateHandle),
    操作系统使用引用计数来控制其生命周期。
      

  16.   

    继续注意,如果另外的进程通过线程ID打开了一个
    线程(OpenThread(...))同样会增加其引用计数,
    此时操作系统会把该线程内核对象的指针挂入进程
    的句柄表中(虽然线程不属于我,可我一样能够占用),
    所以即使线程所属的进程退出了,但该线程内核对象
    的引用计数是1,还存在着,但由于其已经停止运行,
    因此不占用CPU,当该进程结束后,操作系统会将进程
    内核对象句柄表中的所有句柄调用CloseHandle(),减少
    其引用计数。这也是为何内核对象不会导致操作系统资源泄漏
    的原因。
      

  17.   


    你的理解完全错误,如果内核销毁了这个hThread,那该线程如何被
    调度使用CPU时间片?如何在被调度的时候使用THREADCONTEXT进行
    现场保存和切换?
      

  18.   

    如果一定要使用引用计数的说法,只能说它增加或减少。如果要精确地考虑它到底是几,就得看windows的具体实现方法,由于windows用两个Count来实现引用计数,单纯的说引用计数是几是不准确的。