关于_beginthreadex与AfxbeginThread

比较CreateThread,_beginthreadex与AfxbeginThread的文章已经很多了,介绍的已经很详细,其中比较优秀的有:

http://kulong0105.blog.163.com/blog/static/174406191201198104050236/

但是一直有个疑问

如果在线程中既可能使用MFC库,也可能使用C Run-time Library,这时应该使用什么方法创建线程?

尤其是编写SDK框架时,不应该给使用SDK开发人员太多的限制,虽然以上链接文章中已经给出以下一段话:

AfxBeginThread:

         MFC中线程创建的函数,首先创建了相应的CWinThread对象,然后调用CWinThread::CreateThread,在CWinThread::CreateThread中完成了对线程对象的初始化工作,然后,调用_beginthreadex创建线程。注意不要在一个MFC程序中使用_beginthreadex()或CreateThread()。

其中确实提到AfxbeginThread是调用_beginthreadex创建的线程,如果真的如此,那么使用AfxbeginThread创建的线程使用CRT就是安全的,但是网上资料进行此种说明的很少,总是不太放心,于是走查了一下MFC代码,发现了如下的代码:

CWinThread* AFXAPI AfxBeginThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam,
	int nPriority, UINT nStackSize, DWORD dwCreateFlags,
	LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{
#ifndef _MT
	pfnThreadProc;
	pParam;
	nPriority;
	nStackSize;
	dwCreateFlags;
	lpSecurityAttrs;

	return NULL;
#else
	ASSERT(pfnThreadProc != NULL);

	CWinThread* pThread = DEBUG_NEW CWinThread(pfnThreadProc, pParam);
	ASSERT_VALID(pThread);

	if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,
		lpSecurityAttrs))
	{
		pThread->Delete();
		return NULL;
	}
	VERIFY(pThread->SetThreadPriority(nPriority));
	if (!(dwCreateFlags & CREATE_SUSPENDED))
		VERIFY(pThread->ResumeThread() != (DWORD)-1);

	return pThread;
#endif //!_MT)
}

可以看出AfxbeginThread是调用CWinThread的CreateThread方法,再查看CWinThread的CreateThread方法的实现,有如下代码片段

	// create the thread (it may or may not start to run)
	m_hThread = (HANDLE)(ULONG_PTR)_beginthreadex(lpSecurityAttrs, nStackSize,  
		&_AfxThreadEntry, &startup, dwCreateFlags | CREATE_SUSPENDED, (UINT*)&m_nThreadID);

可以看出在CWinThread的CreateThread方法中确实使用的_beginthreadex来创建的线程,所以可以确认在线程中既可能使用MFC库,也可能使用C Run-time Library时,就应该使用AfxbeginThread来创建线程。

可以总结应用场合如下

1、CreateThread,线程中不使用CRT,不使用MFC库

2、_beginthreadex,线程中使用CRT,不使用MFC库,初始化CRT后,调用CreateThread

3、AfxbeginThread,线程中使用CRT,使用MFC库,或者其中任何之一,初始化MFC后,调用_beginthreadex

总之在使用MFC的情况下,不管是否使用CRT,使用AfxbeginThread创建线程都是安全的。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
_beginthreadex是一个Windows平台下的函数,用于创建一个新的线程。它是C/C++语言中的一个函数,用于在一个进程中创建一个新的线程,并且可以指定线程的入口函数、传递参数等。该函数的原型如下: ```c++ unsigned int _beginthreadex( void* security, unsigned stack_size, unsigned (__stdcall* start_address)(void*), void* arglist, unsigned initflag, unsigned* thrdaddr ); ``` 其中,参数说明如下: - security:线程安全属性,默认为NULL。 - stack_size:线程堆栈大小,默认为0。 - start_address:线程入口函数的地址。 - arglist:传递给线程入口函数的参数。 - initflag:线程创建标志,默认为0。 - thrdaddr:用于接收新线程的ID。 而shared_ptr是C++标准库中的智能指针,用于管理动态分配的对象。它提供了自动内存管理的功能,可以自动释放对象的内存空间,避免了手动释放内存的繁琐操作。shared_ptr使用引用计数的方式来管理对象的生命周期,当引用计数为0时,会自动释放对象。 shared_ptr的使用非常简单,可以通过以下方式创建一个shared_ptr对象: ```c++ std::shared_ptr<T> ptr(new T); ``` 其中,T是要管理的对象类型。shared_ptr还支持拷贝构造和赋值操作,可以在多个shared_ptr之间共享同一个对象。 需要注意的是,shared_ptr是通过引用计数来管理对象的生命周期,当最后一个指向对象的shared_ptr被销毁时,会自动释放对象的内存空间。但是,如果存在循环引用的情况,即两个或多个shared_ptr相互引用,会导致内存泄漏。为了避免这种情况,可以使用weak_ptr来解决循环引用的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值