并发运行是操作系统的一个重要功能。有时候程序需要提高运算效率,则需要使用到并发运行。并发运行最直接方便的方式就是创建线程。这里有几个场景是极力推荐使用线程的:
- 在开发MFC程序的时候,如果某个按钮的操作会占用大部分的时间,那么这个时候就应该为这个按钮的执行创建一个线程。如果不这么做,你必须等到这个按钮的所有操作执行完之后才能够点击窗口的其他部分。这个情景就好像你点一个按钮之后程序就直接进入了死机状态(实际上程序仍然在运行,只是这个时候你什么也做不了),这严重影响了用户体验!
- 算法本身需要并发执行的要素,那么这个时候就需要创建线程。
线程的创建很简单,代码如下:
#include <iostream>
#include <Windows.h>
DWORD WINAPI ThreadFun(void* param)
{
//下面是要执行的线程代码
return NULL;
}
int main()
{
HANDLE thread = CreateThread(NULL, NULL, ThreadFun, NULL, 0, 0);
CloseHandle(thread);
Sleep(1);
return 0;
}
在这里,CreateThread函数能够创建一个线程,并返回该线程的句柄。线程创建完之后为挂起状态,需要时间片轮转到该线程,线程才会执行。如果希望线程能够立即得到执行,则需要将当前正在运行的程序设为挂起状态,即执行Sleep函数。
注意到,我们这里创建完线程之后立即执行了CloseHandle。你可能会疑惑为什么创建完线程就立即将其关闭了。其实不是,CloseHandle并没有将线程关闭,而是释放了该线程的句柄而已。释放了句柄意味着我们不能再对该线程进行任何的操作。线程将会在后台继续运行直到完成线程函数中所有指令。
线程的句柄只是提供了操作线程的接口,你可以放弃操作这个线程的权利,但是线程依然会继续运行。
如果你不执行CreateThread,而让该句柄一直保留着,则该句柄将会一直占用内存资源。除非你在创建完句柄之后仍然想继续对句柄进行操作(比如改变该线程的优先级等等操作),否则建议在创建完线程之后立即释放其句柄。