C++多线程——_beginthread()和_beginthreadex

1.函数原型及参数说明

unsigned long _beginthread(
  void(_cdecl *start_address)(void *), //声明为void (*start_address)(void *)形式
  unsigned stack_size, //是线程堆栈大小,一般默认为0
  void *arglist //向线程传递的参数,一般为结构体
);

unsigned long _beginthreadex( //推荐使用
  void *security,	//安全属性,NULL表示默认安全性
  unsigned stack_size, //是线程堆栈大小,一般默认为0
  unsigned(_stdcall  *start_address)(void *),	//声明为unsigned(*start_address)(void *)形式
  void *argilist,	//向线程传递的参数,一般为结构体
  unsigned initflag, //新线程的初始状态,0表示立即执行,CREATE_SUSPEND表示创建后挂起。
  unsigned *thrdaddr //该变量存放线程标识符,它是CreateThread函数中的线程ID。
); //创建成功条件下的将线程句柄转化为unsigned long型返回,创建失败条件下返回0
线程结束:

//释放线程空间、释放线程TLS空间、调用ExiteThread结束线程。
void _endthread(void); 	
// retval:设定的线程结束码,与ExiteThread函数的参数功能一样,
//其实这个函数释放线程TLS空间,再调用ExiteThread函数,但没有释放线程空间。
void _endthreadex(unsigned retval);	
可以显示的调用这两个函数来结束线程。系统从线程启动函数返回时,也会自动调用相应的结束线程函数,收回分配给线程的资源。

两组函数都是用来创建和结束线程的。这两对函数的不同点如下:
(1)从形式上开,_beginthreadex()更像CreateThread()。_beginthreadex()比_beginthread()多3个参数:intiflag,security和threadaddr。
(2)两种创建方式的线程函数不同。_beginthreadex()的线程函数必须调用_stdcall调用方式,而且必须返回一个unsigned int型的退出码。
(3)_beginthreadex()在创建线程失败时返回0,而_beginthread()在创建线程失败时返回-1。这一点是在检查返回结果是必须注意的。
(4)如果是调用_beginthread()创建线程,并相应地调用_endthread()结束线程时,系统自动关闭线程句柄;而调用_beginthreadx()创建线程,并相应地调用_endthreadx()结束线程时,系统不能自动关闭线程句柄。因此调用_beginthreadx()创建线程还需程序员自己关闭线程句柄,以清除线程的地址空间。

下面,同样根据上一节的代码示例采用_beginthreadex来实现,实现代码如下:

#include <Windows.h>
#include <process.h>
#include <iostream>
using namespace std;

typedef struct  _STRUCT_DATA_
{
	int id; //用于标识出票id
	int tickets;
}_DATA,*_pDATA;

CRITICAL_SECTION g_cs;

unsigned __stdcall Fun1Proc(LPVOID lpParam);
unsigned __stdcall Fun2Proc(LPVOID lpParam);

void main()
{
	HANDLE hThread[2] = {NULL,NULL};
	unsigned threadid[2] = {0};
	
	_DATA stru_data;
	stru_data.id = 0;
	stru_data.tickets = 100;
	
	hThread[0] = (HANDLE)_beginthreadex(NULL,0,Fun1Proc,&stru_data,0,&threadid[0]);
	hThread[1] = (HANDLE)_beginthreadex(NULL,0,Fun2Proc,&stru_data,0,&threadid[1]);

	InitializeCriticalSection(&g_cs);
	Sleep(4000);
	LeaveCriticalSection(&g_cs);
}

unsigned __stdcall Fun1Proc(LPVOID lpParam)
{
	_pDATA data = (_pDATA)lpParam;
	while(TRUE)
	{
		EnterCriticalSection(&g_cs);
		if (data->tickets>0)
		{
			Sleep(1);
			cout<<"id: "<<data->id++<<endl;
			cout<<"thread1 sell<<  ticket: "<<data->tickets--<<endl;
			LeaveCriticalSection(&g_cs);
		}
		else
		{
			LeaveCriticalSection(&g_cs);
			break;
		}
	}
	return 0;
}

unsigned __stdcall Fun2Proc(LPVOID lpParam)
{
	_pDATA data = (_pDATA)lpParam;
	while(TRUE)
	{
		EnterCriticalSection(&g_cs);
		if (data->tickets>0)
		{
			Sleep(1);
			cout<<"id: "<<data->id++<<endl;
			cout<<"thread2 sell  ticket: "<<data->tickets--<<endl;
			LeaveCriticalSection(&g_cs);
		}
		else
		{
			LeaveCriticalSection(&g_cs);
			break;
		}
	}
	return 0;
}

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值