线程同步之事件对象

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

    博主在工作中遇到的的一种需求使用了事件对象。项目需求是要连续向服务端发送文件。每发送一个文件服务器端会生成一个id返回给服务器端。但客户端的发送和服务端的回复会采用异步方式,这样就会产生一个问题,如果使用循环连续发送文件,服务器端不一定会按照发送的顺序返回id(也许服务器端会做相应的处理,但我们不应把容错都寄托到别人身上,自己应该尽量避免发生其他人会发生错误)。这时我们可以使用时间对象来避免该情况的发生。

    循环发送的代码如下:     

     HANDLE hSemaphore;
     hSemaphore = CreateEvent(NULL,TRUE,FALSE,NULL);
     for(int m_iIndex=0;m_iIndex<m_vSendFileInfo.size();m_iIndex++)
     {
        string surl,stype; 
        stype = "DOCUMENT";      
        surl = "https://test.sendfile.io";   
        CRestHttpClient msgurl(surl);
        msgurl.addParmas("filename",m_vSendFileInfo[m_iIndex].filename);
        msgurl.addParmas("length",m_vSendFileInfo[m_iIndex].length);
        msgurl.addParmas("type",stype);
        msgurl.DoPut(CBUploadFile,sFileInfo,m_vSendFileInfo[m_iIndex].sFilePath);
        string sTipText = "正在上传文件:" + m_vSendFileInfo[m_iIndex].filename;
        WaitForSingleObject(hSemaphore, 10000);
        ResetEvent(hSemaphore);
     }
  接收端则需要在收到回复后SetEvent(hSemaphore)即可。这样就可以在异步通信中模拟同步时间了。

下面对用到的几个api做一下说明:

       CreateEvent函数创建或打开一个命名的或者匿名的时间对象,该函数原型为:

       HANDLE  CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,
                                             BOOL  bManualReset,

                                              BOOL  bInitialState,

                                              LPCTSTR   lpName);

        lpEventAttributes指向SECURITY_ATTRIBUTES结构体的指针。如果其值为NULL,则使用默认的安全性。

        bManualReset,指定创建的忍冬重置事件对象,还是自动重置事件对象。如果此参数为TRUE,表示该函数将创建一个人工重置事件对象;如果此参数为FALSE,表示该函数将创建一个自动重置事件对象。如果是人工重置事件对象,当线程等待到该对象的所有权之后,需要调用ResetEvent函数手动的将该事件对象设置为无信号状态;如果是自动重置事件对象,当线程等到该函数的所有权之后,系统会自动将该对象设置为无信号状态。

       bInitialState指定事件对象的初始状态。如果此参数值为真,那么该事件对象初始是有信号状态;否则是无信号状态。在该程序中我们设置为false,表示第一次运行到WaitForSingleObject函数处就停止,等到服务器返回后将事件置为有信号状态,才可以向下继续进行。

         lpName指定对象的名称。如果此参数值为NULL,那么将创建一个匿名的事件对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值