folly中的KeepAlive类

发布时间 2024-01-03 13:37:51作者: SchemaL

folly中的KeepAlive

KeepAlive是什么?

本质上是Executor的一个指针,如果Executor支持keepAlive功能,那么只要有一个指向该Executor的KeepAlive对象还存活,那么这个Executor就不会被析构。

KeepAlive实现的原理?

KeepAlive对象本质就是一个uintptr_t(只有一个该成员),但是因为内存对齐的原因,Executor对象的地址总是4的倍数,也就是说Executor*最后两位总是0,KeepAlive在这两位存了信息:最后一位标识所指向的Executor对象是否支持KeepAlive功能(0表示支持),倒数第二位标识Executor对象的析构函数是否需要等待该KeepAlive对象生命周期结束(0表示需要)。

KeepAlive是如何实现让Executor的析构函数等它生命周期结束的呢?

Executor定义了两个接口virtual bool keepAliveAcquire() noexceptvirtual void keepAliveRelease() noexcept,在新建KeepAlive对象的时候,调用keepAliveAcquire接口,在析构的时候调用keepAliveRelease接口,这样Executor对象就知道有几个KeepAlive对象存活了

什么情况下Executor对象不需要等待一个KeepAlive对象的生命周期结束呢?

  • Executor对象不支持KeepAlive功能
  • KeepAlive对象A是调用另一个KeepAlive对象Bget_alias()方法得到的,此时不需要等待A的生命周期结束。这个时候需要保证B的生命周期比A的要长

【TODO】什么情况下会调用get_alias呢?

获取KeepAlive对象的方法?

folly命名空间中,定义了Executor::KeepAlive<ExecutorT> getKeepAliveToken(ExecutorT* executor)Executor::KeepAlive<ExecutorT> getKeepAliveToken(ExecutorT& executor)两个自由模板函数来获取KeepAlive对象,Executor类中也定义了两个同名的static模板方法。另外,folly中还定义了Executor::KeepAlive<ExecutorT> getKeepAliveToken(Executor::KeepAlive<ExecutorT>& ka)来复制一个KeepAlive对象

KeepAlive类的重要属性?

可复制、移动、赋值

可以直接作为Executor对象的指针使用(定义了operator*operator->),可以判空(定义了operator bool)

可以get_alias()获取Executor未记录的KeepAlive对象