利用事件对象实现线程同步

利用事件对象实现线程同步

1)  事件对象也属于内核对象,包含一个使用计数,一个用于指明该事件是一个自动重置的事件还是一个人工重置的事件的布尔值,另一个用于指明该事件处于已通知状态还是未通知状态的布尔值。

2)  有两种不同类型的事件对象。一种是人工重置的事件,另一种是自动重置的事件。当人工重置的事件得到通知时,等待该事件的所有线程均变为可调度线程。当一个自动重置的事件得到通知时,等待该事件的线程中只有一个线程变为可调度线程。

调用CreateEvent创建事件对象,最后用CloseHandle(hevent)来关闭事件对象,hevent为此事件对象的句柄。

在相应线程的执行程序中,用WaitForSingleObject来实现同步,但要注意:在进行同步时,最好用自动重置的事件,由于当一个自动重置的事件得到通知时,等待该事件的线程中只有一个线程变为可调度线程,故在线程中执行完相应操作之后,要使用SetEvent来使得事件处于有信号状态。

三种实现同步方法即使用互斥对象、事件对象与关键代码段的比较

1)  互斥对象和事件对象属于内核对象,利用内核对象进行线程同步,速度较慢,但利用互斥对象和事件对象这样的内核对象,可以在多个进程中的各个线程间进行同步。

2)  关键代码段是工作在用户方式下,同步速度较快,但在使用关键代码段时,很容易进入死锁状态,因为在等待进入关键代码段时无法设定超时值。

 

下面为使用事件对象来模拟简单多线程售卖火车票的例子:

#include <windows.h>

#include <iostream.h>

 

int tickets=100;

HANDLE hevent;

 

DWORD WINAPI Proc1Fun(LPVOID lpParameter);

DWORD WINAPI Proc2Fun(LPVOID lpParameter);

 

main()

{

       HANDLE hthread1;

       HANDLE hthread2;

 

       hthread1=CreateThread(NULL,0,Proc1Fun,NULL,0,NULL);

       hthread2=CreateThread(NULL,0,Proc2Fun,NULL,0,NULL);

 

       hevent=CreateEvent(NULL,FALSE,FALSE,"tickets");

       if(hevent)

       {

              if(ERROR_ALREADY_EXISTS==GetLastError())

              {

                     cout<<"only instance can run!"<<endl;

                     return 1;

              }

       }

 

       SetEvent(hevent);

 

       CloseHandle(hthread1);

       CloseHandle(hthread2);

 

       Sleep(4000);

       CloseHandle(hevent);

 

       return 0; 

}

 

DWORD WINAPI Proc1Fun(LPVOID lpParameter)

{

       while(TRUE)

       {

              WaitForSingleObject(hevent,INFINITE);

              if(tickets>0)

              {

                     Sleep(1);

                     cout<<"Thread1 sells ticket"<<tickets--<<endl;

              }

              else

                     break;

              SetEvent(hevent);

 

       }

       return 0;

}

 

 

DWORD WINAPI Proc2Fun(LPVOID lpParameter)

{

       while(TRUE)

       {

              WaitForSingleObject(hevent,INFINITE);

              if(tickets>0)

              {

                     Sleep(1);

                     cout<<"Thread2 sells ticket"<<tickets--<<endl;

              }

              else

                     break;

              SetEvent(hevent);

       }

       return 0;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值