CreateThread与_beginthread的区别是? CreateThread与_beginthread的区别是?注意事项是? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 CreateThread系统API;_beginthread,c/C++实时库函数,其中调用CreateThread;_beginthread可跨平台,建议使用_beginthread 摘自《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值。 总的说来,_beginthreadex就是先做了很多其他工作,来保证在多线程条件下,C++运行期库能够正常运作,然后在调用CreatetThread,在线程退出后,,_beginthreadex还保证了对C++运行期库的一些清理工作 LS是说在多数情况下要优先使用_beginthread??欢迎继续讨论 如果你的程序中不使用C/C++运行期库,那用CreatetThread没什么问题。但是如果你的程序中使用了C/C++运行期库,那就必须用_beginthread/_beginthreadex(这两个的区别就是参数不一样,你能得到的信息不一样,对线程控制的权利不一样) 使用CreateThread会有哪些后果,如何选用? 内存泄露、有些C/C++函数在不同的线程下会得到不可预知的结果。早期的C/C++开发小组没有考虑到多线程情况,使用了全局变量,在函数内部使用了静态变量,这些变量就会有“线程同步”的问题 _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 );} LS是说在多数情况下要优先使用_beginthread?? 关于OpenGL的一点应用问题,新手! PPP协议!链路建立过程得不到iP地址! 各位,有难题,在对话框中插入什么控件,可以在上面输入一个小数,然后赋给一个变量 做过操作系统课程设计的帮帮忙! DirectX3D错误? 如何判断一个字符串是否为有效路径? 小菜的几个小问题,望多执教!谢谢!!! 那位大虾帮忙? 请问如何删除一个类? 非模态对话框显示问题 关于TopMost问题 这是一段用CPen画线的代码,请大家帮我看看问题出在那里了?非常感谢!!
_beginthread,c/C++实时库函数,其中调用CreateThread;
_beginthread可跨平台,建议使用_beginthread
2.传递给_beginthreadex的线程函数的地址保存在tiddata内存块中。传递给该函数的参数也
保存在该数据块中。
3._beginthreadex确实从内部调用CreateThread,因为这是操作系统了解如何创建新线程的
唯一方法。
4.当调用CreatetThread时,它被告知通过调用_threadstartex而不是pfnStartAddr来启动执行
新线程。还有,传递给线程函数的参数是tiddata结构而不是pvParam的地址
5.如果一切顺利,就会像CreateThread那样返回线程句柄。如果任何操作失败了,便返回
NULL_beginthreadex和_beginthread函数的区别。_beginthread函数的参数比较少,因此比特性全面的_beginthreadex函数受到更大的限制。
例如,如果使用_beginthread,就无法创建带有安全属性的新线程,无法创建暂停的线程,也
无法获得线程的ID值。
早期的C/C++开发小组没有考虑到多线程情况,使用了全局变量,在函数内部使用了静态变量,这些变量就会有“线程同步”的问题
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 );
}