一、创建一个线程
创建线程使用CreateThread
The CreateThread function creates a thread to execute within the address space of the calling process.
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize, 指定初始提交栈的大小
LPTHREAD_START_ROUTINE lpStartAddress,
//由线程执行,表示线程的起始地址,指定线程入口函数,
//该入口函数的参数类型以及返回类型要与ThreadProc()函数声明的类型要保持一致
LPVOID lpParameter, //指定一个单独的值传递给线程
DWORD dwCreationFlags, //指定控件线程创建的附加标记
LPDWORD lpThreadId ); //指向一个用来接收线程的标识符变量
参数1:指向SECURITY_ATTRIBUTES结构体的指针。这里可以设置为NULL,使用缺省的安全性。
参数2:指定初始提交的栈的大小,以字节为单位。系统会将这个值四舍五入为最近的页面。
(页面:是系统管理内存时使用的内存单位,不同的CPU其页面大小也是不同的。X86
使用的页面大小是4KB。当保留地址空间的一个区域时,系统要确保该区域的大小是
系统的页面大小的倍数)
如果该值是0或者小于缺省提交大小,则使用和调用线程一样的大小。
参数3:指向LPTHREAD_START_ROUTINE(应用程序定义的函数类型)的指针。这个函数将被线程
执行,表示了线程的起始地址。看线程入口函数ThreadProc。
参数4:指定传递给线程的单独的参数的值。
参数5:指定控制线程创建的附加标记。如果CREATE_SUSPENDED标记被指定,线程创建后处于暂停
状态不会运行,直到调用了ResumeThread函数。
如果该值是0,线程在创建之后立即运行。
参数6:[out]指向一个变量用来接收线程的标识符。创建一个线程时,系统会为线程分配一个ID号。
Windows NT/2000:如果这个参数是NULL,线程的标识符不会返回。
Windows 95/98 :这个参数不能是NULL
如果线程创建成功,此函数返回线程的句柄。
---------------------------------------------------------------------------------
二、编写线程函数
可参考ThreadProc:
DWORD WINAPI ThreadProc(LPVOID lpParameter);
---------------------------------------------------------------------------------
三、关闭线程句柄
在主线程中创建完一个新线程之后,一般会调用CloseHandle()方法来关闭新创建的线程的句柄。
BOOL CloseHandle(HANDLE hObject);
注意:
关闭句柄并没有终止新创建的线程,新建的线程继续在运行。
至于为什么要关闭线程句柄,主要有两个原因:
1.在本主线程中,这个句柄已经没什么用了。
2.当关闭线程句柄时和创建的线程执行完毕之后,系统会递减新线程的内核对象使用计数,
当使用计数为0时,系统就会释放线程内核对象;
如果在主线程中没有关闭这个句柄,那么始终会保留这个引用,
这样线程的内核对象的使用计数即使在创建的线程执行完毕之后也不会降为0,
因此线程的内核对象无法释放,直到进程终止时系统才会清理这些残留的对象。
所以应该在不再使用线程的句柄的时候将其关闭掉,让线程的线程内核对象的引用计数减1。
--------------------------------------------------------------------------------
四、暂停线程的执行
当线程暂停执行的时候,也就是表示它放弃了执行的权力。
操作系统会从等待运行的线程队列中选择一个线程来运行。新创建的线程就可以得到运行的机会。
可以使用函数Sleep:
void Sleep(
DWORD dwMilliseconds //sleep time 以毫秒为单位
);
暂停当前线程指定时间间隔的执行。
--------------------------------------------------------------------------------