线程是程序中一个单一的顺序控制流程。在单个程序中同时运行多个线程完成不同的工作,称为多线程。
以上来自百度百科。多线程技术会让程序变得更加强大,是单线程永远无法实现的。例如,在命令行中,用户正在响应getchar函数,而我需要在用户输入的同时将命令行标题改为现在的时间,这个效果是单线程永远不可能达到的。学习了本教程的内容,上面的例子就不难做到。
首先,认识API函数CreateThread:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
参数及其复杂,但事实上在普通的编程中大多数参数基本不需要用到。直接看示例代码:
void Thread1()
{
while(1)
{
system("title %time%");
}
}
void main(int argc, char* argv[])
{
HANDLE hThread;
DWORD ThreadID;
hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread1,NULL,0,&ThreadID);
getchar();
}
(如果提示getchar未定义,请加入stdio.h头文件)
是否实现了我们例子中想要的效果?让我们来分析一下代码。
首先,在main函数中使用API函数CreateThread创建了一个线程,线程的内容就是执行Thread1函数(参数三),然后就到了getchar函数中等待用户的输入完成。而在此同时,刚刚创建的线程正在执行Thread1函数的内容,就是不断地将命令行标题设置为当前时间。于是,我们的效果便达成了。
CreateThread返回的是线程的HANDLE,示例代码中是保存在hThread变量中。CreateThread会将第五个参数设置为线程的ID。线程的HANDLE和ID都是很重要的参数,对以后线程的其他操作有很重要的意义。
-----------------------------------------------------------------------分割线----------------------------------------------------------------------------------------------------------------------
CreateThread参数说明:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // [in,可选] 句柄是否可被继承 ,为NULL则不可被继承
DWORD dwStackSize, //堆栈的初始大小,如为0系统自动分配
LPTHREAD_START_ROUTINE lpStartAddress, //指向由线程执行的应用程序定义函数的指针。
LPVOID lpParameter, //指向要传递给线程的变量的指针。
DWORD dwCreationFlags, //控制线程创建的标志。为0该线程在创建后立即运行;其它可选标志看下文.
LPDWORD lpThreadId //指向接收线程标识符的变量的指针。如果此参数为 NULL,则不返回线程标识符。
);
DWORD dwCreationFlags //可选标志
- 0 该线程在创建后立即运行。
- CREATE_SUSPENDED(0x00000004) 该线程在挂起状态下创建,并且不会运行,直到 ResumeThread函数被调用。
- STACK_SIZE_PARAM_IS_A_RESERVATION(0x00010000) 在所述dwStackSize参数指定堆栈的初始保留大小。如果未指定此标志,则dwStackSize指定提交大小。
-----------------------------------------------------------------------分割线----------------------------------------------------------------------------------------------------------------------
那么,再介绍几个API函数,这几个函数比较简单,请读者们自由测试:
DWORD SuspendThread(
HANDLE hThread
);
这个是挂起线程的API函数,用于暂停线程的执行。参数为创建线程时返回的线程HANDLE。
DWORD ResumeThread(
HANDLE hThread
);
这个是继续执行线程的API函数,用于将已经挂起的线程恢复执行,与SuspendThread对应。参数为创建线程时返回的线程HANDLE。
VOID ExitThread(
DWORD dwExitCode
);
这个是停止(销毁)线程的API函数,只能在线程内部使用。参数为退出码,一般可设为0。
BOOL TerminateThread(
HANDLE hThread,
DWORD dwExitCode
);
这个是强行停止(销毁)线程的API函数,能在程序的任意部分使用。但是使用这一API函数来终止线程是不安全的,可能造成程序不稳定。不推荐使用。参数一为创建线程时返回的线程HANDLE,参数二为退出码,一般可设为0。