当前位置: 首页 > news >正文

计算机专业主要学什么前景怎么样企业网站优化公司

计算机专业主要学什么前景怎么样,企业网站优化公司,深圳建设工程中标公示,西安网站建设聚星互联fiber协程模块 以下是从sylar服务器中学的,对其的复习; sylar的fiber协程模块是基于ucontext_t实现非对称协程 函数只有两个行为:调用与返回。一旦函数返回后,它在栈上所拥有的状态将被销毁。协程相比函数多了两个动作&#xf…

fiber协程模块

以下是从sylar服务器中学的,对其的复习;

  • sylar的fiber协程模块是基于ucontext_t实现非对称协程

函数只有两个行为:调用与返回。一旦函数返回后,它在栈上所拥有的状态将被销毁。协程相比函数多了两个动作:挂起与恢复。当协程主动挂起时,它的控制权将转交给另一个协程,这时它所拥有的状态仍被保留着,另一个协程获取控制权后,在将来某个时间点也可能选择挂起,从而使原协程的控制权得以恢复,一旦协程像函数一样返回,它所拥有的状态将被销毁。

协程是能暂停执行以在之后恢复的函数。

同样是单线程环境下,协程的yield和resume一定是同步进行的,一个协程的yield,必然对应另一个协程的resume,因为线程不可能没有执行主体。并且,协程的yield和resume是完全由应用程序来控制的。与线程不同,线程创建之后,线程的运行和调度也是由操作系统自动完成的,但协程创建后,协程的运行和调度都要由应用程序来完成,就和调用函数一样,所以协程也被称为用户态线程。

所谓创建协程,其实就是把一个函数包装成一个协程对象,然后再用协程的方式把这个函数跑起来;所谓协程调度,其实就是创建一批的协程对象,然后再创建一个调度协程,通过调度协程把这些协程对象一个一个消化掉(协程可以在被调度时继续向调度器添加新的调度任务);所谓IO协程调度,其实就是在调度协程时,如果发现这个协程在等待IO就绪,那就先让这个协程让出执行权,等对应的IO就绪后再重新恢复这个协程的运行;所谓定时器,就是给调度协程预设一个协程对象,等定时时间到了就恢复预设的协程对象。

ucontext_t接口

// 上下文结构体定义
typedef struct ucontext_t {// 当前上下文结束后,下一个激活的上下文对象的指针,只在当前上下文是由makecontext创建时有效struct ucontext_t *uc_link;// 当前上下文的信号屏蔽掩码sigset_t          uc_sigmask;// 当前上下文使用的栈内存空间,只在当前上下文是由makecontext创建时有效stack_t           uc_stack;// 平台相关的上下文具体内容,包含寄存器的值mcontext_t        uc_mcontext;...
} ucontext_t;// 获取当前的上下文
int getcontext(ucontext_t *ucp);// 恢复ucp指向的上下文,这个函数不会返回,而是会跳转到ucp上下文对应的函数中执行,相当于变相调用了函数
int setcontext(const ucontext_t *ucp);// 修改由getcontext获取到的上下文指针ucp,将其与一个函数func进行绑定,支持指定func运行时的参数,
// 在调用makecontext之前,必须手动给ucp分配一段内存空间,存储在ucp->uc_stack中,这段内存空间将作为func函数运行时的栈空间,
// 同时也可以指定ucp->uc_link,表示函数运行结束后恢复uc_link指向的上下文,
// 如果不赋值uc_link,那func函数结束时必须调用setcontext或swapcontext以重新指定一个有效的上下文,否则程序就跑飞了
// makecontext执行完后,ucp就与函数func绑定了,调用setcontext或swapcontext激活ucp时,func就会被运行
void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);// 恢复ucp指向的上下文,同时将当前的上下文存储到oucp中,
// 和setcontext一样,swapcontext也不会返回,而是会跳转到ucp上下文对应的函数中执行,相当于调用了函数
int swapcontext(ucontext_t *oucp, const ucontext_t *ucp);

sylar协程模块设计

sylar使用非对称协程模型,也就是子协程只能和线程主协程切换,而不能和另一个子协程切换,并且在程序结束时,一定要再切回主协程,以保证程序能正常结束

sylar对每个协程,设计了6种状态

/*** @brief 协程状态*/
enum State {/// 初始化状态INIT,/// 暂停状态HOLD,/// 执行中状态EXEC,/// 结束状态TERM,/// 可执行状态READY,/// 异常状态EXCEPT
};

fiber类包含以下成员变量

/// 协程id
uint64_t m_id        = 0;
/// 协程栈大小
uint32_t m_stacksize = 0;
/// 协程状态
State m_state        = READY;
/// 协程上下文
ucontext_t m_ctx;
/// 协程栈地址
void *m_stack = nullptr;
/// 协程入口函数
std::function<void()> m_cb;

定义了两个全局静态变量,用于生成协程id和统计当前的协程数

/// 全局静态变量,用于生成协程id
static std::atomic<uint64_t> s_fiber_id{0};
/// 全局静态变量,用于统计当前的协程数
static std::atomic<uint64_t> s_fiber_count{0};

以下两个线程局部变量用于保存协程上下文信息

/// 线程局部变量,当前线程正在运行的协程
static thread_local Fiber *t_fiber = nullptr;
/// 线程局部变量,当前线程的主协程,切换到这个协程,就相当于切换到了主线程中运行,智能指针形式
static thread_local Fiber::ptr t_thread_fiber = nullptr;

构造函数
带参数的构造函数用于构造子协程,初始化子协程的ucontext_t上下文和栈空间,要求必须传入协程的入口函数,以及可选的协程栈大小。不带参的构造函数用于初始化当前线程的协程功能,构造线程主协程对象

/*** @brief 构造函数* @attention 无参构造函数只用于创建线程的第一个协程,也就是线程主函数对应的协程,* 这个协程只能由GetThis()方法调用,所以定义成私有方法*/
Fiber::Fiber(){SetThis(this);m_state = RUNNING;if (getcontext(&m_ctx)) {SYLAR_ASSERT2(false, "getcontext");}++s_fiber_count;m_id = s_fiber_id++; // 协程id从0开始,用完加1SYLAR_LOG_DEBUG(g_logger) << "Fiber::Fiber() main id = " << m_id;
}/*** @brief 构造函数,用于创建用户协程* @param[] cb 协程入口函数* @param[] stacksize 栈大小,默认为128k*/
Fiber::Fiber(std::function<void()> cb, size_t stacksize): m_id(s_fiber_id++), m_cb(cb) {++s_fiber_count;m_stacksize = stacksize ? stacksize : g_fiber_stack_size->getValue();m_stack     = StackAllocator::Alloc(m_stacksize);if (getcontext(&m_ctx)) {SYLAR_ASSERT2(false, "getcontext");}m_ctx.uc_link          = nullptr;m_ctx.uc_stack.ss_sp   = m_stack;m_ctx.uc_stack.ss_size = m_stacksize;makecontext(&m_ctx, &Fiber::MainFunc, 0);SYLAR_LOG_DEBUG(g_logger) << "Fiber::Fiber() id = " << m_id;
}/*** @brief 返回当前线程正在执行的协程* @details 如果当前线程还未创建协程,则创建线程的第一个协程,* 且该协程为当前线程的主协程,其他协程都通过这个协程来调度,也就是说,其他协程* 结束时,都要切回到主协程,由主协程重新选择新的协程进行resume* @attention 线程如果要创建协程,那么应该首先执行一下Fiber::GetThis()操作,以初始化主函数协程*/
Fiber::ptr GetThis(){if (t_fiber) {return t_fiber->shared_from_this();}Fiber::ptr main_fiber(new Fiber);SYLAR_ASSERT(t_fiber == main_fiber.get());t_thread_fiber = main_fiber;return t_fiber->shared_from_this();
}

协程原语的实现,挂起和恢复

/*** @brief 将当前协程切换到运行状态(与调度协程)* @pre getState() != EXEC* @post getState() = EXEC*/
void Fiber::swapIn() {SetThis(this);SYLAR_ASSERT(m_state != EXEC);m_state = EXEC;if(swapcontext(&Scheduler::GetMainFiber()->m_ctx, &m_ctx)) {SYLAR_ASSERT2(false, "swapcontext");}
}/*** @brief 将当前协程切换到后台(与调度协程)*/
void Fiber::swapOut() {SetThis(Scheduler::GetMainFiber());if(swapcontext(&m_ctx, &Scheduler::GetMainFiber()->m_ctx)) {SYLAR_ASSERT2(false, "swapcontext");}
}/*** @brief 将当前线程切换到执行状态(与主协程)* @pre 执行的为当前线程的主协程*/
void Fiber::call() {SetThis(this);m_state = EXEC;SYLAR_LOG_ERROR(g_logger) << getId();if(swapcontext(&t_threadFiber->m_ctx, &m_ctx)) {SYLAR_ASSERT2(false, "swapcontext");}
}/*** @brief 将当前线程切换到后台(与主协程)* @pre 执行的为该协程* @post 返回到线程的主协程*/
void Fiber::back() {SetThis(t_threadFiber.get());if(swapcontext(&m_ctx, &t_threadFiber->m_ctx)) {SYLAR_ASSERT2(false, "swapcontext");}
}

协程入口函数

void Fiber::MainFunc() {Fiber::ptr cur = GetThis(); // GetThis()的shared_from_this()方法让引用计数加1SYLAR_ASSERT(cur);cur->m_cb(); // 这里真正执行协程的入口函数cur->m_cb    = nullptr;cur->m_state = TERM;auto raw_ptr = cur.get(); // 手动让t_fiber的引用计数减1cur.reset();raw_ptr->yield(); // 协程结束时自动yield,以回到主协程
}

协程的重置
重复利用已结束的协程,复用其栈空间,创建新协程

void Fiber::reset(std::function<void()> cb) {SYLAR_ASSERT(m_stack);SYLAR_ASSERT(m_state == TERM);m_cb = cb;if (getcontext(&m_ctx)) {SYLAR_ASSERT2(false, "getcontext");}m_ctx.uc_link          = nullptr;m_ctx.uc_stack.ss_sp   = m_stack;m_ctx.uc_stack.ss_size = m_stacksize;makecontext(&m_ctx, &Fiber::MainFunc, 0);m_state = READY;
}

http://www.yidumall.com/news/79499.html

相关文章:

  • 做的网站怎样适配手机做网站推广的公司
  • 单位网站建设的优势手机app推广平台
  • wordpress近期文章杭州百度快照优化排名
  • 启航网站建设国内专业的seo机构
  • alexa怎么查询网站排名百度一下你就知道官网下载安装
  • 内江做网站的公司一链一网一平台
  • 医疗不可以做网站百度网盘网页版
  • 男女怎么做那个视频网站起名最好的网站排名
  • 购物网站页面布局百度一下你就知道123
  • 网站建设与维护试卷创新驱动发展战略
  • 网站建设需要懂什么装修公司网络推广方案
  • 吉林省人民政府电话广州谷歌seo
  • 网站商城首页怎么做吸引人最近新闻大事
  • 自己的网站怎么做关键词电商软文范例300字
  • 网站建设理由文明seo技术教程网
  • 响应式网站模板滚动条海南网站制作
  • 夫唯徒弟做外贸服装批发的seo案例 用wp做的网站德兴网站seo
  • zencart网站管理上海站群优化
  • mysql数据做彩票网站全网推广的方式
  • 做网站软件frontpage百度指数搜索榜
  • 营销型企业网站建设案例他达拉非片的作用及功效副作用
  • 国内做免费的视频网站媒体软文发布平台
  • 无锡微信网站怎样优化网络
  • 注册网站获取网易邮箱安全码东莞建设网
  • 做百度竞价用什么网站移动端优化
  • 赌博网站做维护犯罪关键词排名快照优化
  • 领创科技网站开发泰安做网站公司哪家比较好
  • 桂林做网站公司北京seo关键词排名优化
  • 公司做网站的目的浏览器直接进入网站的注意事项
  • 做播放器电影网站需要多少钱6企业网站设计规范