【动手写协程库 5】常用IO函数的HOOK功能

【动手写协程库】系列笔记是学习sylar的协程库时的记录,参考了从零开始重写sylar C++高性能分布式服务器框架和代码随想录中的文档。文章并不是对所有代码的详细解释,而是为了自己理解一些片段所做的笔记。 hook函数的具体定义实现可以在这里查看:Github: src/hook.cpp 该协程库框架的目标并不是做成类似goroutine那样,而是希望能够通过协程来提高IO处理的效率。因此,对于每个文件描述符fd,我们都希望它有一个读写IO的超时时间。 hook的目的是在不重新编写代码的情况下,把老代码中的socket IO相关的API都转成异步,以提高性能。 ...

2024-09-30 · 1 min · 108 words · Kerolt

【动手写协程库 4】IO协程调度器

【动手写协程库】系列笔记是学习sylar的协程库时的记录,参考了从零开始重写sylar C++高性能分布式服务器框架和代码随想录中的文档。文章并不是对所有代码的详细解释,而是为了自己理解一些片段所做的笔记。 IOManager类中具体定义实现可以在这里查看:Github: src/iomanager.cpp 之前实现的协程调度器的功能其实非常简单,当添加任务后调度器只是单纯的从任务队列中取出任务交给协程去执行。sylar的协程库的关注对象是网络IO,如果采用这么简单的调度就根本没有用到协程的精髓。 sylar的IO协程调度解决了之前调度器在idle状态下忙等待导致CPU占用率高的问题。IO协程调度器使用一对管道fd来tickle调度协程,当调度器空闲时,idle协程通过epoll_wait阻塞在管道的读描述符上,等管道的可读事件。添加新任务时,tickle方法写管道,idle协程检测到管道可读后退出,调度器执行调度。 ...

2024-09-29 · 4 min · 782 words · Kerolt

【动手写协程库 3】定时器

【动手写协程库】系列笔记是学习sylar的协程库时的记录,参考了从零开始重写sylar C++高性能分布式服务器框架和代码随想录中的文档。文章并不是对所有代码的详细解释,而是为了自己理解一些片段所做的笔记。 TimerManager类中具体定义实现可以在这里查看:Github: src/timer.cpp 通过定时器,我们可以实现给服务器注册定时事件。sylar的定时器采用最小堆设计,所有定时器根据绝对的超时时间点(也就是超时到期的具体时间戳)进行排序,每次取出离当前时间最近的一个超时时间点,计算出超时需要等待的时间,然后等待超时。超时时间到后,获取当前的绝对时间点,然后把最小堆里超时时间点小于这个时间点的定时器都收集起来,执行它们的回调函数。 ...

2024-09-28 · 1 min · 192 words · Kerolt

【动手写协程库 2】协程调度器

【动手写协程库】系列笔记是学习sylar的协程库时的记录,参考了从零开始重写sylar C++高性能分布式服务器框架和代码随想录中的文档。文章并不是对所有代码的详细解释,而是为了自己理解一些片段所做的笔记。 Scheduler类中其他函数的定义可以在这里查看:Github: src/scheduler.cpp Sylar的协程调度器是一个N-M模型,意味着N个线程可以运行M个协程,协程能够在线程之间进行切换,也可以被绑定到特定的线程上执行。 调度器可以由应用程序中的任何线程创建,但创建它的线程(称为caller线程)可以选择是否参与协程的调度。如果caller线程参与调度,那么调度器的线程数会相应减少一个,因为caller线程本身也会作为一个调度线程。 ...

2024-09-11 · 2 min · 402 words · Kerolt

【动手写协程库 1】协程定义

【动手写协程库】系列笔记是学习sylar的协程库时的记录,参考了从零开始重写sylar C++高性能分布式服务器框架和代码随想录中的文档。文章并不是对所有代码的详细解释,而是为了自己理解一些片段所做的笔记。 Coroutine类中其他函数的定义可以在这里查看:Github: src/coroutine.cpp 对于什么是协程,为什么要使用协程,可以看看之前的笔记:【协程】C++20协程初体验。 对于我们自己来实现协程,其实在之前Xv6的Lab中就有做过:【MIT6.S081】Lab6 multithreading,当初做这个lab的时候没有意识到这就是协程。协程的切换最重要的就是要保存和恢复上下文,在这个lab中,我们通过保存每个协程在切换之前的寄存器的值,以此可用来恢复原来的执行流。 ...

2024-09-10 · 2 min · 325 words · Kerolt

【协程】C++是如何通过SFINAE来检查promise_type的

我们知道在C++20的协程中,自己实现的Coroutine中必须包含一个Promise,并且这个Promise必须要实现: get_return_object() initial_suspend() final_suspend() unhandled_exception() 少了其中任何一个,编译器都会报错。那这是怎么实现的呢?如果是像java那样是一个接口而没有对应的实现从而报错还能理解,但是我们的代码中的Promise完完全全是我们自己写的,也没有使用继承,编译器你怎么知道我在实现协程时少了什么东西呢? 答案就是:SFINAE(Substitution Failure Is Not An Error,替换失败不是错误)。 ...

2024-09-01 · 1 min · 109 words · Kerolt

【协程】C++20协程初体验

为什么我们需要协程? 为什么我们有了线程还需要协程呢?(其实这个问题不应该这么问,协程的出现在线程之前)在一个进程中虽然我们可以创建多个线程,但是在一个进程中能创建的线程数量是有限制的,并且线程的调度仍然受操作系统控制,也就是说线程何时抢占、何时被抢占对于开发者来说都是透明的,并且在调度的过程中还可能涉及到用户态和内核态的切换开销。 ...

2024-08-18 · 2 min · 266 words · Kerolt