代码改变世界

多线程一 CreateThread与_beginthreadex的本质区别

2012-08-23 09:54  javaspring  阅读(280)  评论(0编辑  收藏  举报

1、尽量使用_beginthreadex()来代替使用CreateThread(),为什么?   

    _beginthreadex()函数在创建新线程时会分配并初始化一个_tiddata块。这个_tiddata块自然是用来存放一些需要线程独享的数据。事实上新线程运行时会首先将_tiddata块与自己进一步关联起来。然后新线程调用标准C运行库函数如strtok()时就会先取得_tiddata块的地址再将需要保护的数据存入_tiddata块中。这样每个线程就只会访问和修改自己的数据而不会去篡改其它线程的数据了。因此,如果在代码中有使用标准C运行库中的函数时,尽量使用_beginthreadex()来代替CreateThread()相信阅读到这里时,你会对这句简短的话有个非常深刻的印象,如果有面试官问起,你也可以流畅准确的回答了^_^

2、WaitForSingleObject函数

   WaitForSingleObject函数功能:等待函数使线程进入等待状态,直到指定的内核对象被触发。

    函数原形:DWORDWINAPIWaitForSingleObject(HANDLEhHandle,DWORDdwMilliseconds);

    函数说明:第一个参数为要等待的内核对象。第二个参数为最长等待的时间,以毫秒为单位,如传入5000就表示5秒,传入0就立即返回,传入INFINITE表示无限等待。

    因为线程的句柄在线程运行时是未触发的,线程结束运行,句柄处于触发状态。所以可以用WaitForSingleObject()来等待一个线程结束运行。

3、实例程序

    由于是多线程程序,事先记得配置VC环境,Project->Settings->C/C++->Code Generation->Use run-time libray->Debug Multithread,或 Multithread,或 Debug Multithread DLL, 或 Multithread DLL都可以,即Use run-time library需要使用多线程的。

#include <windows.h>
#include <process.h>    /* _beginthread, _endthread */
#include <stdio.h>

int g_nCount;

//子线程函数,注意格式
unsigned int __stdcall ThreadFun(PVOID pM)
{
	g_nCount++;
	printf("线程ID号为%4d的子线程报数%d\n", GetCurrentThreadId(), g_nCount);
	return 0;
}

//主函数,所谓主函数其实就是主线程执行的函数。
int main()
{
	printf("     子线程报数 \n");
	printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");
	
	const int THREAD_NUM = 10;
	HANDLE handle[THREAD_NUM];	
	g_nCount = 0;

	for (int i = 0; i < THREAD_NUM; i++)
		handle[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFun, NULL, 0, NULL);

	WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
	return 0;
}

      答案并没有像我们想象中的顺序数数输出1到10,这是为什么呢,请看下节。

 

文章转载于:http://blog.csdn.net/morewindows/article/details/7421759