CreateThread与_beginthread的区别是?
CreateThread与_beginthread的区别是?注意事项是? 问题点数:10、回复次数:10Top
1 楼crearo(铜板)回复于 2006-12-04 10:52:30 得分 2
CreateThread系统API;
_beginthread,c/C++实时库函数,其中调用CreateThread;
_beginthread可跨平台,建议使用_beginthread
Top
2 楼nizhaorong()回复于 2006-12-04 10:58:51 得分 0
还有什么不同?Top
3 楼Fly_1101()回复于 2006-12-04 11:04:19 得分 2
摘自《windows 核心编程》:
CreateThread函数是用来创建线程的Windows函数。不过,如果你正在编写C/C++代码,决不应该调用CreateThread。相反,应该使用Visual C++运行期库函数_beginthreadex。如果不使用Microsoft的Visual C++编译器,你的编译器供应商有它自己的CreateThred替代函数。
若要使多线程C和C++程序能够正确地运行,必须创建一个数据结构,并将它与使用C/C++运行期库函数的每个线程关联起来。当你调用C/C++运行期库时,这些函数必须知道查看调用线程的数据块,这样就不会对别的线程产生不良影响。
1.每个线程均获得由C/C++运行期库的堆栈分配的自己的tiddata内存结构。
2.传递给_beginthreadex的线程函数的地址保存在tiddata内存块中。传递给该函数的参数也
保存在该数据块中。
3._beginthreadex确实从内部调用CreateThread,因为这是操作系统了解如何创建新线程的
唯一方法。
4.当调用CreatetThread时,它被告知通过调用_threadstartex而不是pfnStartAddr来启动执行
新线程。还有,传递给线程函数的参数是tiddata结构而不是pvParam的地址
5.如果一切顺利,就会像CreateThread那样返回线程句柄。如果任何操作失败了,便返回
NULL
_beginthreadex和_beginthread函数的区别。_beginthread函数的参数比较少,因此比特性全面的_beginthreadex函数受到更大的限制。
例如,如果使用_beginthread,就无法创建带有安全属性的新线程,无法创建暂停的线程,也
无法获得线程的ID值。Top
4 楼Fly_1101()回复于 2006-12-04 11:06:15 得分 3
总的说来,_beginthreadex就是先做了很多其他工作,来保证在多线程条件下,C++运行期库能够正常运作,然后在调用CreatetThread,在线程退出后,,_beginthreadex还保证了对C++运行期库的一些清理工作Top
5 楼nizhaorong()回复于 2006-12-04 11:12:52 得分 0
LS是说在多数情况下要优先使用_beginthread??欢迎继续讨论Top
6 楼Fly_1101()回复于 2006-12-04 11:17:04 得分 0
如果你的程序中不使用C/C++运行期库,那用CreatetThread没什么问题。但是如果你的程序中使用了C/C++运行期库,那就必须用_beginthread/_beginthreadex(这两个的区别就是参数不一样,你能得到的信息不一样,对线程控制的权利不一样)Top
7 楼nizhaorong()回复于 2006-12-04 11:17:18 得分 0
使用CreateThread会有哪些后果,如何选用?Top
8 楼Fly_1101()回复于 2006-12-04 11:23:13 得分 0
内存泄露、有些C/C++函数在不同的线程下会得到不可预知的结果。
早期的C/C++开发小组没有考虑到多线程情况,使用了全局变量,在函数内部使用了静态变量,这些变量就会有“线程同步”的问题Top
9 楼Fly_1101()回复于 2006-12-04 11:35:52 得分 2
_beginthreadex的源代码:
uintptr_t __cdecl _beginthreadex (
void *security,
unsigned stacksize,
unsigned (__stdcall * initialcode) (void *),
void * argument,
unsigned createflag,
unsigned *thrdaddr
)
{
_ptiddata ptd; /* pointer to per-thread data */
uintptr_t thdl; /* thread handle */
unsigned long errcode = 0L; /* Return from GetLastError() */
unsigned dummyid; /* dummy returned thread ID */
if ( initialcode == NULL ) {
errno = EINVAL;
return( (uintptr_t)0 );
}
/*
* Allocate and initialize a per-thread data structure for the to-
* be-created thread.
*/
if ( (ptd = _calloc_crt(1, sizeof(struct _tiddata))) == NULL )
goto error_return;
/*
* Initialize the per-thread data
*/
_initptd(ptd);
ptd->_initaddr = (void *) initialcode;
ptd->_initarg = argument;
ptd->_thandle = (uintptr_t)(-1);
/*
* Make sure non-NULL thrdaddr is passed to CreateThread
*/
if ( thrdaddr == NULL )
thrdaddr = &dummyid;
/*
* Create the new thread using the parameters supplied by the caller.
*/
if ( (thdl = (uintptr_t)
CreateThread( security,
stacksize,
_threadstartex,
(LPVOID)ptd,
createflag,
thrdaddr))
== (uintptr_t)0 )
{
errcode = GetLastError();
goto error_return;
}
/*
* Good return
*/
return(thdl);
/*
* Error return
*/
error_return:
/*
* Either ptd is NULL, or it points to the no-longer-necessary block
* calloc-ed for the _tiddata struct which should now be freed up.
*/
_free_crt(ptd);
/*
* Map the error, if necessary.
*
* Note: this routine returns 0 for failure, just like the Win32
* API CreateThread, but _beginthread() returns -1 for failure.
*/
if ( errcode != 0L )
_dosmaperr(errcode);
return( (uintptr_t)0 );
}Top
10 楼chary8088(天使鱼儿)回复于 2006-12-04 13:04:28 得分 1
LS是说在多数情况下要优先使用_beginthread??Top




