线程同步—事件对象

    1、事件对象3个成员:

          1) 使用计数;

          2)指定是自动重置事件对象还是人工重置对象;

          3)指明是初始状态,是有信号状态,还是无线号状态;

   2、事件对象类型:

          1)人工重置事件对象;

          2)自动重置事件对象;

   3、人工重置事件对象和自动重置事件对象的区别:

          当人工重置的事件对象得到通知时,等待该事件对象的所有线程均变为可调度线程;当自动重置的事件对象得到通知时,等待该事件的线程中只有一个线程变为可调度的线程,同时操作系统会将该事件对象设置为无信号状态,这样当对所保护的代码执行完成后,需要调用SetEvent()函数将该事件对象设置为有信号状态。而人工事件对象,在一个线程得到该事件对象之后,操作系统并不会将该事件对象设置为无信号状态,除非现实滴调用ResetEvent()函数将其设置为无信号状态。否则该对象会一直是有信号状态。

    4、代码:

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>


DWORD WINAPI Fun1Proc (
        LPVOID lpParameter
        );
DWORD WINAPI Fun2Proc(
       LPVOID lpParameter
       );
;
int index=0;
int tickets=100;
HANDLE hEvent;
void main()
{
   HANDLE hThread1;
   HANDLE hThread2;

   int a;

//第一个参数:指向LPSECURITY_ATTRIBUTES  结构体 的指针;

//第二个参数:指定是自动重置事件对象(TRUE)还是人工重置对象(false);

//第三个参数:指明是初始状态,是有信号状态(TRUE),还是无线号状态(false);

//第四个参数:指明事件对象的名称;


   hEvent = CreateEvent(NULL,false,TRUE,NULL);//如果第三个参数为false,结果会怎样?请思考!

   hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
   hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
   CloseHandle(hThread1);
   CloseHandle(hThread2);

   scanf("%d",&a);
   CloseHandle(hEvent);

}

DWORD WINAPI Fun1Proc(
       LPVOID lpParameter   // thread data
       )
{
   while(TRUE)
   {
      WaitForSingleObject(hEvent,INFINITE);
      if(tickets>0)
        {
          Sleep(1);
          printf("thread1 sell ticket : %d \n",tickets--);
        }
     else
        break;

    SetEvent(hEvent);// 如果把这个参数注释掉,会怎样?
   }
 return 0;
}

DWORD WINAPI Fun2Proc(
       LPVOID lpParameter   // thread data
       )
{
     while(TRUE)
         {
              WaitForSingleObject(hEvent,INFINITE);
              if(tickets>0)
                {
                  Sleep(1);
                  printf("thread1 sell ticket : %d \n",tickets--);
                }
             else
                    break;

            SetEvent(hEvent);
         }

 return 0;
}

 /**********************************************************************************************************************************为了实现线程同步,尽量不要使用人工重置对象,应该很容易出错,比如,如果是单核,你要考虑执行到某条语句时,会出现时间片到了,跳去执行另外一个线程;如果是多核,几个线程又是同时执行的,又会出现复杂的情况的。如果是自动的事件对象,一个线程得到改事件对象,那么操作系统会把该事件对象设置为无信号,这样其他线程就无法得到这个事件对象了,但也要注意,你使用完后,你要记住把这个事件对象设为有信号,要不然其他线程是得不到这个事件对象的。

***********************************************************************************************************************************/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值