1。我的理解,进程/线程Id可以唯一标识一个进程,进程handle也是唯一标识一个进程,all right ?
2。一个进程/线程为什么要有两个唯一标识符?它们用途有什么分工?

解决方案 »

  1.   

    关于句柄
                                          句柄的本质(CSDN)受M$的帮助文档以及很多Windows编程书籍的影响,大家对局柄比较普遍的认识是:句柄
    是一个整数,用以标识Windows对象,句柄不是一个指针……
    而实际上,这些不过是M$进行数据封装的幌子而已,下面我们一起来分析一下HANDLE到底
    是什么。
    请先到Windef.h找绝大多数句柄的定义:
    DECLARE_HANDLE(HWND);
    DECLARE_HANDLE(HHOOK);
    ……
    DECLARE_HANDLE(HGDIOBJ);
    DECLARE_HANDLE(HBITMAP);
    DECLARE_HANDLE(HBRUSH);
    ……
    typedef HANDLE              HGLOBAL;
    typedef HANDLE              HLOCAL;
    ……
    OK, 现在大家跟我一起翻到Winnt.h,看看DECLARE_HANDLE和HANDLE到底是什么:
    #ifdef STRICT
    typedef void *HANDLE;
    #define DECLARE_HANDLE(name) struct name##__ { int unused; };
    typedef struct name##__ *name
    #else
    typedef PVOID HANDLE;
    #define DECLARE_HANDLE(name) typedef HANDLE name
    #endif
    typedef HANDLE *PHANDLE;
    哈哈,现在知道了吧,HANDLE就是PVOID,也就是无类型指针,
    而DECLARE_HANDLE(HWND);就是:
    struct HWND__ {
        int unused;};
    typedef struct HWND__ *HWND;
    现在实际上都清楚啦,这些Handles都不过是指向struct的指针,至于这个struct的用处
    ,连M$都说unused了,^o^
    现在解释下M$这么做的意义,这就是所谓数据封装,你可以在你的程序中把M$的内部结
    构指针传来传去,可是你却不知道它到底指向的内容是什么,
    而且可以编个句柄的瞎话防止大家的质疑:)。而M$的程序大可以这么写:
    #include <windows.h>  //这个和大家用的一样
    #include "windows_in.h"  //这个是M$自用的,外人别想看到^o^
    HSOMETHINGELSE DoSomething(HSOMETHING hSomething) {
        struct RealSomething* p = (struct RealSomething*)hSomething; //先强制类型
                                                              //转换成内部结构指针
        ……do something……
        return (HSOMETHINGELSE)pRealSomethingElse;//强制类型逆转换
    }这段同样转载自CSDN,指明使用句柄而不是内存地址来使用对象的作用。句柄是一个32位的整数,实际上是WINDOWS在内存中维护的一个对象(窗口等)内存物
    理地址列表的整数索引。因为WINDOWS的内存管理经常会将当前空闲对象的内存释放掉,
    当需要时访问再重新提交到物理内存。所以对象的物理地址是变化的,不允许程序直接
    通过物理地址来访问对象。程序将想访问的对象的句柄传递给系统,系统根据句柄检索
    自己维护的对象列表就能知道程序想访问的对象及其物理地址了。
      

  2.   

    其实很好理解,一个进程可以是同一个名字,比如svchost.exe但是到底是哪个svchost.exe呢,可以是d:\drsmart\cwj\svchost.exe的,也可能是系统的如何区分呢pid就是process id嘛
      

  3.   

    学习 lizhongbin(闪客) 说的内容!
      

  4.   

    线程ID:这个线程的编号
    线程HANDLE:这个线程函数在内存中的地址
      

  5.   

    我的理解是ID是全系统唯一的,应用此ID可以在系统中的任何应用程序标示此进程或者线程。而HANDLE则是进程相关的,同样的一个进程线程,在不同的应用程序中它的值是不一样的。一般来说内核对象的HANDLE是其在内核对象表中的INDEX,而并不是前面有人所说的内存地址。要说明这一点很简单,你看一下这些HANDLE的值就知道了。这些值往往都是很小的值,在98和me下经常出现1,2,3这样的值,而在xp出现的往往也就几百左右,而对于地址来说,这些地址都是属于非法地址。而那些非内核对象的HANDLE则有可能是地址。
      

  6.   

    楼上很奇怪,这里没有人说ID是GUID我说全系统唯一,是指本次系统启动的过程中,存在的进程和线程中,不会有重复的ID