C++多线程之_beginthread

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013043408/article/details/83830181

标准C运行时库函数,需要包含头文件process.h。

创建线程

uintptr_t _beginthread( 
   void (__cdecl *start_address)(void* fun),//线程执行函数,__cdecl
   unsigned stack_size,                     //线程的堆栈大小,0,默认大小(1M)
   void *arglist                            //线程执行函数的参数
);

uintptr_t _beginthreadex(
   void *security,        //安全属性,NULL,默认安全属性
   unsigned stack_size,   //线程的堆栈大小,0,默认大小(1M)
   unsigned (__stdcall *start_address)(void* fun), //线程执行函数,__stdcall
   void *arglist,         //线程执行函数的参数
   unsigned initflag,     //线程的初始状态,,0:立即执行;CREATE_SUSPENDED:挂起
   unsigned *thrdaddr     //返回线程的ID
);

1、_beginthread错误返回-1,_beginthreadex错误返回0。
2、这两个API都可以创建线程,但_beginthreadex比_beginthread更安全些。MSDN上的解释大概是这样的:用_beginthread创建线程时,如果线程执行函数瞬间返回,可导致_beginthread返回线程句柄无效或是另一个线程句柄。同时,_beginthreadex创建的线程初始状态可以为挂起,这样能更好地控制线程状态。

在执行函数中结束线程

void _endthread(void); 
void _endthreadex(unsigned retval);

1、这两个API在线程执行函数中调用,会立即结束线程。若在执行函数外调用,不会结束线程。
2、_endthread和_endthreadex都会释放线程的资源,比如thread local storage(TLS)。但_endthreadex不会释放线程句柄,需要手动调用WIN32API CloseHandle释放。
3、线程执行函数返回后,会自动调用_endthread或_endthreadex。

_endthread导致的内存泄漏

调用_endthread后,线程执行函数结束。但它没有释放在执行函数中new的内存,同时,对于在函数中定义的类对象,它的析构函数不会执行(详细讲一下)。如果这个类是这样定义的,在构造函数中new了内存,并在析构函数中释放。很显然,内存泄漏。

代码示例

class MyClass
{
public:
	MyClass(){cout << "MyClass enter" << endl;}
	~MyClass(){cout << "MyClass exit" << endl;}
};

void fun1(void* param)
{
	MyClass mycl;
	_endthread();//主要测试对象,观察注释和不注释时,输出结果
}

int main()
{
	_beginthread(fun1, 0, NULL);
	getchar();
	return 0;
}

输出
注释_endthread()时:
MyClass enter
MyClass exit

不注释时:
MyClass enter

不完整的接口

遗憾的是,C运行库没有提供挂起线程和唤醒线程功能。下一步研究WIN32创建线程方法,可以弥补这一点。

猜你喜欢

转载自blog.csdn.net/u013043408/article/details/83830181
今日推荐