c++多线程

1.题目
3个线程a,b,c。分别打印A , B , C 。用这3个线程循环打印ABC10次,即输出ABCABCABC...
 
2.分析
    1)如何创建子线程
           CreateThread是Windows API函数,该函数在主线程的基础上创建一个新线程。

            CreateThread创建一个新的线程的大致步骤如下:
                a. 在内核对象中分配一个线程标识/句柄,可供管理,由CreateThread返回
                b.把线程退出码置为STILL_ACTIVE,把线程挂起计数设置为1
                c.分配context结构
                d.IpStartAddr和IpvThread值被放在栈顶,使它们成为传送给StartOfThread的参数
                e.把context结构的栈指针指向栈顶(d)指令指针指向startOfThread函数
            
            用法:
            HANDLE hThread = CreateThread(&security_attributes, dwStackSize, ThreadProc,pParam, dwFlags, &idThread) ;
          参数说明:
                    第一个参数表示线程内核对象的安全属性,一般传入NULL表示使用默认设置。
                    第二个参数表示线程栈空间大小。传入0表示使用默认大小(1MB)。
                    第三个参数表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址。
                    第四个参数是传给线程函数的参数。
                    第五个参数指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()。
                    第六个参数将返回线程的ID号,传入NULL表示不需要返回该线程ID号。
          函数返回值:    
                    成功返回新线程的句柄,失败返回NULL。 

    2)现在已经生成了3个线程,如何让这3个线程循环打印呢?要实现循环打印就是要实现线程之间的同步a->b->c->a->b->c....
        CreateEvent()常用于线程之间的同步。
    
         用法:
          hEvent = CreateEvent(NULL,TRUE,TRUE,NULL); 
            参数说明:
                    第一个参数表示确定返回的句柄是否可被子进程继承。如果lpEventAttributes是NULL,此句柄不能被继承。 
                    第二个参数表示指定将事件对象创建成手动复原还是自动复原。如果是TRUE,那么必须用ResetEvent函数来手工将事件的状态复原到无信号状态。如果设置为FALSE,当一个等待线程被释放以后,系统将会自动将事件状态复原为无信号状态。 
                    第三个参数表示指定事件对象的初始状态。如果为TRUE,初始状态为有信号状态;否则为无信号状态。 
                    第四个参数表示指定事件的对象的名称,是一个以0结束的字符串指针 。
            函数返回值:
                    如果函数调用成功,函数返回事件对象的句柄。


     3)如何使用事件对象.
            为了使用事件对象,常用的3个函数为:SetEvent、ResetEvent和WaitForSingleObject。
            BOOL SetEvent(HANDLE hEvent); //将事件对象置为有信号
            BOOL ResetEvent(HANDLE hEvent); //将事件对象置为无信号
            DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);//等待一个事件有信号或者定时时间到。第一个参数为事件对象句柄,第二个参数是定时时间
            

       4)整体思路:使用全局数组,放入3个事件对象,开启3个线程,每个线程等待相对应的事件,打印完成之后将后面的事件置为有信号。
            在主线程中使用 WaitForMultipleObjects(3, hThread, TRUE, INFINITE)等待所有线程完成,之后,退出主线程。

3.代码
HANDLE  g_ThreadEvent[3];//事件对象数组
int g_EventIndex = 0;
DWORD WINAPI ThreadFunc(void *p)
{
	int param=(int)p;
	char c='A'+param;
	for(int iIndex =0; iIndex < 10; iIndex ++)
	{
		//线程ABC分别等待事件0,1,2
		WaitForSingleObject(g_ThreadEvent[param], INFINITE);//等待信号
		printf("the thread is %c\n",c);
		ResetEvent(g_ThreadEvent[g_EventIndex]);//将对应的信号置为无
		g_EventIndex = (g_EventIndex+1)%3;
		SetEvent(g_ThreadEvent[g_EventIndex]);//将下一个信号置为有信号
	}
	return 0;
}
int main(int argc, char* argv[])
{
	//全为自动模式一次只能进去一个
	for(int iIndex = 0; iIndex < 3; iIndex++)
	{
		g_ThreadEvent[iIndex] = CreateEvent(NULL, falsefalse, NULL);
	}
	SetEvent(g_ThreadEvent[0]);
	HANDLE hThread[3];
	for(int iIndex = 0; iIndex < 3; iIndex++)
	{
		hThread[iIndex] = (HANDLE)CreateThread(NULL, 0,ThreadFunc, (void *)iIndex, 0, NULL);
	}
	//等待所有线程结束
	WaitForMultipleObjects(3, hThread, TRUE, INFINITE);
	cout<<"运行结束,按任意键退出.....\n";
	char c= getchar();
	CloseHandle(g_ThreadEvent);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值