google base库中的WaitableEvent
这个类说白了就是对windows event的封装,没有什么特别的,常规做法,等侍另一线程无非就是等侍事件置信waitsingleobject,通知事件无非就是setevent,一看就明白,不就详解,写在这里只是为了这个系更的完整性
下边的示例代码注意下:
// WaitableEvent *e = new WaitableEvent;
// SendToOtherThread(e);
// e->Wait();
// delete e;
SendToOtherThread(e); 这个应当就是开启另外一个线程什么的,然后将事件传递过去,然后等侍事情做完以后再继续,这是这样写的话还不如将要写的代码写在当前线程,看来还没明白它的深意,具体用在什么样的场景比较好
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. #ifndef BASE_SYNCHRONIZATION_WAITABLE_EVENT_H_
#define BASE_SYNCHRONIZATION_WAITABLE_EVENT_H_ #include "base/base_export.h"
#include "base/basictypes.h" #if defined(OS_WIN)
#include <windows.h>
#endif #if defined(OS_POSIX)
#include <list>
#include <utility>
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#endif namespace base { // This replaces INFINITE from Win32
static const int kNoTimeout = -1; class TimeDelta; // A WaitableEvent can be a useful thread synchronization tool when you want to
// allow one thread to wait for another thread to finish some work. For
// non-Windows systems, this can only be used from within a single address
// space.
//
// Use a WaitableEvent when you would otherwise use a Lock+ConditionVariable to
// protect a simple boolean value. However, if you find yourself using a
// WaitableEvent in conjunction with a Lock to wait for a more complex state
// change (e.g., for an item to be added to a queue), then you should probably
// be using a ConditionVariable instead of a WaitableEvent.
//
// NOTE: On Windows, this class provides a subset of the functionality afforded
// by a Windows event object. This is intentional. If you are writing Windows
// specific code and you need other features of a Windows event, then you might
// be better off just using an Windows event directly.
class BASE_EXPORT WaitableEvent {
public:
// If manual_reset is true, then to set the event state to non-signaled, a
// consumer must call the Reset method. If this parameter is false, then the
// system automatically resets the event state to non-signaled after a single
// waiting thread has been released.
WaitableEvent(bool manual_reset, bool initially_signaled); #if defined(OS_WIN)
// Create a WaitableEvent from an Event HANDLE which has already been
// created. This objects takes ownership of the HANDLE and will close it when
// deleted.
explicit WaitableEvent(HANDLE event_handle); // Releases ownership of the handle from this object.
HANDLE Release();
#endif ~WaitableEvent(); // Put the event in the un-signaled state.
void Reset(); // Put the event in the signaled state. Causing any thread blocked on Wait
// to be woken up.
void Signal(); // Returns true if the event is in the signaled state, else false. If this
// is not a manual reset event, then this test will cause a reset.
bool IsSignaled(); // Wait indefinitely for the event to be signaled. Wait's return "happens
// after" |Signal| has completed. This means that it's safe for a
// WaitableEvent to synchronise its own destruction, like this:
//
// WaitableEvent *e = new WaitableEvent;
// SendToOtherThread(e);
// e->Wait();
// delete e;
void Wait(); // Wait up until max_time has passed for the event to be signaled. Returns
// true if the event was signaled. If this method returns false, then it
// does not necessarily mean that max_time was exceeded.
//
// TimedWait can synchronise its own destruction like |Wait|.
bool TimedWait(const TimeDelta& max_time); #if defined(OS_WIN)
HANDLE handle() const { return handle_; }
#endif // Wait, synchronously, on multiple events.
// waitables: an array of WaitableEvent pointers
// count: the number of elements in @waitables
//
// returns: the index of a WaitableEvent which has been signaled.
//
// You MUST NOT delete any of the WaitableEvent objects while this wait is
// happening, however WaitMany's return "happens after" the |Signal| call
// that caused it has completed, like |Wait|.
static size_t WaitMany(WaitableEvent** waitables, size_t count); // For asynchronous waiting, see WaitableEventWatcher // This is a private helper class. It's here because it's used by friends of
// this class (such as WaitableEventWatcher) to be able to enqueue elements
// of the wait-list
class Waiter {
public:
// Signal the waiter to wake up.
//
// Consider the case of a Waiter which is in multiple WaitableEvent's
// wait-lists. Each WaitableEvent is automatic-reset and two of them are
// signaled at the same time. Now, each will wake only the first waiter in
// the wake-list before resetting. However, if those two waiters happen to
// be the same object (as can happen if another thread didn't have a chance
// to dequeue the waiter from the other wait-list in time), two auto-resets
// will have happened, but only one waiter has been signaled!
//
// Because of this, a Waiter may "reject" a wake by returning false. In
// this case, the auto-reset WaitableEvent shouldn't act as if anything has
// been notified.
virtual bool Fire(WaitableEvent* signaling_event) = 0; // Waiters may implement this in order to provide an extra condition for
// two Waiters to be considered equal. In WaitableEvent::Dequeue, if the
// pointers match then this function is called as a final check. See the
// comments in ~Handle for why.
virtual bool Compare(void* tag) = 0; protected:
virtual ~Waiter() {}
}; private:
friend class WaitableEventWatcher; #if defined(OS_WIN)
HANDLE handle_;
#else
// On Windows, one can close a HANDLE which is currently being waited on. The
// MSDN documentation says that the resulting behaviour is 'undefined', but
// it doesn't crash. However, if we were to include the following members
// directly then, on POSIX, one couldn't use WaitableEventWatcher to watch an
// event which gets deleted. This mismatch has bitten us several times now,
// so we have a kernel of the WaitableEvent, which is reference counted.
// WaitableEventWatchers may then take a reference and thus match the Windows
// behaviour.
struct WaitableEventKernel :
public RefCountedThreadSafe<WaitableEventKernel> {
public:
WaitableEventKernel(bool manual_reset, bool initially_signaled); bool Dequeue(Waiter* waiter, void* tag); base::Lock lock_;
const bool manual_reset_;
bool signaled_;
std::list<Waiter*> waiters_; private:
friend class RefCountedThreadSafe<WaitableEventKernel>;
~WaitableEventKernel();
}; typedef std::pair<WaitableEvent*, size_t> WaiterAndIndex; // When dealing with arrays of WaitableEvent*, we want to sort by the address
// of the WaitableEvent in order to have a globally consistent locking order.
// In that case we keep them, in sorted order, in an array of pairs where the
// second element is the index of the WaitableEvent in the original,
// unsorted, array.
static size_t EnqueueMany(WaiterAndIndex* waitables,
size_t count, Waiter* waiter); bool SignalAll();
bool SignalOne();
void Enqueue(Waiter* waiter); scoped_refptr<WaitableEventKernel> kernel_;
#endif DISALLOW_COPY_AND_ASSIGN(WaitableEvent);
}; } // namespace base #endif // BASE_SYNCHRONIZATION_WAITABLE_EVENT_H_
google base库中的WaitableEvent的更多相关文章
- google base库之simplethread
// This is the base SimpleThread. You can derive from it and implement the // virtual Run method, or ...
- base库中的BarrierClosure
说明说得很明白,就是等侍num_closures 为零的时候回调done_closure,代码也很简单,不加详述 #ifndef BASE_BARRIER_CLOSURE_H_ #define BAS ...
- google base 之MessagePumpForUI
base库中比较有意思就是这个类了,如同很多界面库一样,创建了一个隐藏窗口来处理需要在界面线程处理的消息,大体原理也就是需要执行task的时候发送一个自定义的消息,当窗口接收到task的时候调用保存起 ...
- colmap编译过程中出现,无法解析的外部符号错误 “__cdecl google::base::CheckOpMessageBuilder::ForVar1(void)”
错误提示: >colmap.lib(matching.obj) : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: cl ...
- Chromium base库分割字符串SplitString
前一段时间在工作过程中遇到一个场景需要将http response中的request header中的cookie字段取出并进行解析,但是手头没有解析cookie的工具类,同时cookie的表现就是个 ...
- 删除本地git版本库中受版本控制的文件
git乱码解决方案汇总 乱码原因 搜索一番,发现git文件名.log乱码,是普遍问题,这其中有编码的原因,也有跨平台的原因.主要原因是Windows 系统中的Git对中文文件名采用不同的编码保存所致 ...
- SVN Error: “' 'x' isn't in the same repository as 'y' ” during merge (并不在同一个版本库中)
在使用svn merge命令报错 英文版本:SVN Error: “' 'x' isn't in the same repository as 'y' ” during merge 中文版本报错:并不 ...
- 第一个lucene程序,把一个信息写入到索引库中、根据关键词把对象从索引库中提取出来、lucene读写过程分析
新建一个Java Project :LuceneTest 准备lucene的jar包,要加入的jar包至少有: 1)lucene-core-3.1.0.jar (核心包) 2) lucene- ...
- python学习笔记——urllib库中的parse
1 urllib.parse urllib 库中包含有如下内容 Package contents error parse request response robotparser 其中urllib.p ...
随机推荐
- C#版QQTea加密
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Wind ...
- android _scrollview嵌套listview出现高度显示不全解决方案
只要在工具类里写上这一段代码:/** * scrollview嵌套listview显示不全解决 * @param listView */ public static void setListViewH ...
- 【MFC学习笔记-作业5-小数据库】【单选框,复选框,滚动条,列表框】
界面已经实现完毕. 要完成的操作就是1.性别分组(2选1) 2.属性勾选 3.年龄通过滚动条调整 4.职称通过下方的列表框选择 5.输入姓名 6.存入左方的列表框 7.当选择左方列表框的人时,可以显示 ...
- 【最大流之sap】【HDU1532】模板题
与上题一样 纯属测试模板 来自kuangbin的模板 #include <cstdio> #include <cstdlib> #include <cmath> # ...
- 关于ASP.NET中的负载均衡
ASP.NET站点中做负载均衡: 基于HTTP协议我们可能发现我们要解决两点问题: 第一做到负载均衡,我们需要一个负载均衡器. 可以通过DNS轮询来做,在DNS服务器上配置为每次对我们做负载均衡的同一 ...
- (转)DataTable添加行出现“该行已经属于另一个表”的错误!
1 DataTable dt1 = new DataTable(); DataTable dt2 = new DataTable(); //为dt1创建结构 DataColumn pName = ne ...
- There is no satiety in study
好不容易考上了硕士.这个时候,才终于明白什么叫做学无止境.用了1周linux,发现需要学习的东西太多了.life is too short to learn c plus plus 果然如此.不过我们 ...
- js/jquery获取当前页面URL地址并判断URL字符串中是否包含某个具体值
js/jquery获取当前页面URL地址并判断URL字符串中是否包含某个具体值本文介绍jquery/js获取当前页面url地址的方法,在jquery与js中获取当前页面url方法是一样的,因为jque ...
- centos6.7配置git服务器
1.yum install -y git 2.adduser git 3.cd /data/git 没有则创建该目录 git init --bare test.git;创建一个裸仓库,没有工作区,不需 ...
- CentOS DNS resolv重启无效的解决方法
分类: LINUX 直接修改/etc/resolv.conf不行.必须要在/etc/sysconfig/network-scripts/ifcfg-eth0里面最后 加上dns的设置.要不然,重启后, ...