help wanted
Repository metrics
- Stars
- (12,016 stars)
- PR merge metrics
- (Avg merge 1d) (6 merged PRs in 30d)
Description
Workflow支持异步文件IO任务,具体实现目前在Linux下是由操作系统支持的异步IO系统,在非Linux的系统下是用多线程实现的。而Windows下目前也这个需求,所以欢迎熟悉iocp开发的小伙伴可以积极参与共建~
在此把原异步文件IO的流程大概梳理如下,以供参考:
- 用户层接口,我们以
create_pread_task()为例子:
class WFTaskFactory
{
static WFFileIOTask *create_pread_task(const std::string& pathname,
void *buf,
size_t count,
off_t offset,
fio_callback_t callback);
...
- Workflow内部都是行为派生,所以用户拿到的都是
WFFileIOTask *类型的task,而内部会根据pread行为创建一个__WFFilepreadTask:
WFFileIOTask *WFTaskFactory::create_pread_task(const std::string& pathname,
void *buf,
size_t count,
off_t offset,
fio_callback_t callback)
{
return new __WFFilepreadTask(pathname, buf, count, offset,
WFGlobal::get_io_service(),
std::move(callback));
}
__WFFilepreadTask需要实现prepare(),供内部IOService调用,具体是做与异步文件相关的起始操作:
class __WFFilepreadTask : public WFFilepreadTask
{
protected:
virtual int prepare()
{
// 这里调用了IOSession层的prep_preadv(),不同系统实现不一样;
}
- 在Linux和Windows中,WFFileTask和IORequest的定义都是一样的。不同点在于上面提到的IOService和IOSession。 IOService是接管所有文件异步IO的服务,IOSession是一次IO请求的上下文,需要根据Windows下iocp的机制来具体实现。 虽然Linux使用了系统的libaio,但大家要做的事情是类似:
class IOService
{
public:
int request(IOSession *session); // 用于用户提交一个文件io任务
private:
int event_fd; // 用于结合libaio机制的eventfd,多个IO事件也只用一个,希望在windows下也尽量少占用系统资源
private:
struct list_head session_list; // 用链表管理了此时发出的多个任务
private:
static void *aio_finish(void *context); // 用于结合libaio机制的回调函数,有事件通知会回到这里
...
};
- 此IOService需要通过
CommScheduler::io_bind()把自己的eventfd和回调绑定到通信器中,同理也需要io_unbind()。其他内部接口需要根据iocp的机制按需添加。目的是做到当系统有异步事件的时候,会通过注册到通信器的机制来告诉框架,框架调起当时的那片上下文的handle(),即可回到task的逻辑中:
void Communicator::handle_aio_result(struct poller_result *res)
{
...
session->handle(state, error);
- 如果希望默认使用此异步文件服务,可以参考现在的
__FileIOService, 从IOService派生,并且在全局单例中提供接口供调用,这样也可以保证不用异步文件IO的用户不会创建相应资源:
class __CommManager
{
IOService *get_io_service()
{
if (!fio_flag_)
fio_service_ = new __FileIOService(&scheduler_);
...
}
}
以上是整个异步文件IO的基本流程,希望在windows下的实现同时遵循Workflow一如既往的对资源的极度节制以及对高并发的严谨。如有了解iocp的小伙伴愿意尝试欢迎随时交流。