转自:http://www.chenhangyu.com/?p=175
创建线程的函数有很多种, 包括CreateThread、_beginthread、 _beginthreadex和AfxBeginThread. 用法在MSDN上都有详述, 这里做个笔记摘录.
1, CreateThread是不安全的,很多参考书上,都说不要用CreateThread 创建线程、并用CloseHandle来关闭这个线程,因为一些技术性的问题,会导致内存泄漏. 直接在CreateThread API创建的线程中使用sprintf,malloc,strcat等涉及CRT存储堆操作的CRT库函数是不安全的.
2, _beginthread和_beginthreadex在CreateThread上做了改进,可以安全的进行操作但是,必须在线程结束的时候相应的调用_endthread或_endthreadex.
3, beginthreadex比_beginthread更安全一些,beginthread隐式调用了CloseHandle关闭了线程句柄,而与_beginthreadex成对使用的_endthreadex则没有关闭线程的句柄,需要显示调用CloseHandle来关闭线程句柄,从逻辑上更安全.
4, 在MFC程序中,使用AfxBeginThread.
5, 在非MFC程序中,尽量使用_beginthreadex.
使用_beginthreadex启动线程和传递参数的例子:
#include "windows.h"
#include "stdio.h"
#include "process.h"
typedef struct
{
int seqno;
}PARA_T;
HANDLE hHendle;
DWORD threadProc(LPVOID pParameter); //线程调用的函数
void main(int argc, char* argv[])
{
int i;
// 跑5个线程
for (i=0; i<5; ++i)
{
PARA_T aPara;
aPara.seqno = i;
_beginthreadex(NULL, 0, (void *)&threadProc, (void *)&aPara, 0, hHendle);
Sleep(500);
}
getchar();
}
DWORD threadProc(LPVOID pParameter)
{
iPara = (PARA_T *)pParameter;
printf("-----%d\n",iPara->seqno);
return 0;
}
结果是:
—–0
—–1
—–2
—–3
—–4
一些需要注意的地方:
1,线程依赖于主进程,主进程退出了,线程也都退出.所以例子这里是getchar在等待,同样,可以使用一个状态位+while循环来判断线程是否处理完毕.在这个例子里,要是把Sleep(500); 和 getchar()都去掉, 运行一下,就会明白这个意思了.
2,CloseThread函数并不是把线程咔嚓了,而是把线程句柄咔嚓了. 线程执行完就会return,就当做一个函数执行完一样退出.在这里close的意思是, 主进程放弃对线程的控制了.
3,关于参数的传递,使用结构体方式更好一些, 新定义或者new一个结构体, 也避免了使用直接变量做为参数的时候被外部条件改变值.