1、 句柄
1)伪句柄:GetCurrentThread()、GetCurrentProcess得到的句柄是伪句柄,只能在本线程、进程中使用。
2)什么是句柄?句柄的作用?通过传递句柄给系统API,获取相关资源。句柄相当于一个加密后的指针,避免用户直接操作内核对象。
2、 一些系统API返回值的含义
1) WAIT_ABANDONED:Thespecified object is a mutex object that was not released by the thread thatowned the mutex object before the owning thread terminated. Ownership of themutex object is granted to the calling thread, and the mutex is set tononsignaled.是WaitForSingleObject返回值之一,表示创建该互斥量的线程在终止时没有释放互斥量,调用线程返回,但是互斥量依然标识为无信号。对于互斥量来讲如果正在被使用则为无信号状态,被释放后变为有信号状态。
3、 内核对象和用户对象
内核对象句柄与进程相关,同一对象在不同的进程中句柄是不同的,传递内核对象句柄给其他进程时需要调用DuplicateHandle()。而用户对象句柄与进程无关,在不同进程中可以直接使用。另外内核对象创建时都有一个安全属性参数,用户对象没有。LPSECURITY_ATTRIBUTESlpEventAttributes。内核对象举例:进程对象、线程对象、Mutex对象、Event对象等。用户对象举例:窗口、字体、画刷等。
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle, // handle to the source process
HANDLE hSourceHandle, // handle to duplicate
HANDLE hTargetProcessHandle, // handle to process toduplicate to
LPHANDLE lpTargetHandle, // pointer to duplicate handle
DWORD dwDesiredAccess, // access for duplicate handle
BOOL bInheritHandle, // handle inheritance flag
DWORD dwOptions // optional actions
)
4、 CreateThread、_beginthreadex和_beginthread
CreateThread是系统API,其余二者是C运行时库函数
区别主要是体现在多线程编程时
- 使用malloc(),free(),new
- 调用stdio.h或io.h,包括fopen(),open(),getchar(),write(),printf(),errno
- 使用浮点变量和浮点运算函数
- 调用那些使用静态缓冲区的函数如:localtime(),asctime(),strtok(),rand()等。
CRT库
LIBC.LIB Single thread static library, retail version
LIBCMT.LIB Multithread static library, retail version
MSVCRT.LIB Import library for MSVCRT.DLL, retail version
CreateThread和_beginthreadex
在使用多线程的CRT库时上述函数需要使用单独的线程局部存储数据块,而CreateThead创建线程时没有分配该数据块。运行时库函数试图TlsGetvalue获取线程数据块的地址,如果没有获取到,函数就会现场分配一个tiddata结构,并且和线程相关联。而_beginthreadex为每个线程分配自己的tiddata内存结构。该结构保存了许多像errno这样的变量和函数的值、地址。
MSDN引用
You can call _endthread or _endthreadex explicitlyto terminate a thread; however, _endthread or _endthreadex is calledautomatically when the thread returns from the routine passed as a parameter to _beginthread or _beginthreadex.Terminating a thread with a call to endthread or _endthreadex helps ensureproper recovery of resources allocated for the thread.
For an executable filelinked with Libcmt.lib, do not call the Win32 ExitThread API;this prevents the run-time system from reclaiming allocated resources._endthread and _endthreadex reclaim allocated thread resources and then call ExitThread
线程返回return时会调用_endthreadex和_endthread,而二者会释放多线程CRT库函数分配的线程局部存储块tiddata。
_beginthreadex和_beginthread
前者可以设置线程的栈大小,安全属性等。后者不行。
5、 ExitThread、_endthreadex和_endthread
|
调用局部变量析构函数 |
释放线程局部存储块tiddata |
Return |
Y |
Y(indirectly) |
Endthreadex/_endthread |
N |
Y |
ExitThread |
N |
N |
_endthreadex和_endthread
前者可以带返回值,不调用CloseHandle关闭线程句柄,后者不能带返回值,会自动关闭线程句柄。
6、 SendMessage和PostMessage
1) SendMessage()直接把一个消息发给窗口过程,等消息被接收线程处理后才返回。Postmessage()只是把消息发送到消息队列,完成后即返回。
2) PostMessage的返回值表示PostMessage函数执行是否正确,SendMessage的返回值表示其他程序处理消息后的返回值.
3) PostMessage发向目标窗口的消息一定会进入消息队。SendMessage向同一线程的窗口发消息,不会进入消息队列,向其他线程的窗口发消息,则会进入消息队列。