Muduo学习笔记之EventLoop巧妙的线程切换

从上面两篇博文可知,每个线程有且只有一个EventLoop对象,其中IO线程是老大,线程池里面的线程只负责处理某一个客户端的请求。那么,如何从非IO线程切换到IO线程呢?EventLoop类里面新增了一个RuninLoop()函数。如果用户在当前IO线程调用这个函数,回调会同步进行,如果用户在其他线程调用这个函数,cb(用户回调函数)会被假如IO线程的队列,IO线程将被唤醒来调用这个cb。这里我感觉设计的特别巧妙,也是muduo作者的过人之处。

在这里插入图片描述
有了这个函数,我们就可以轻易的在线程间调配任务,将非IO线程的函数移到IO线程,这样还可以在不用锁的情况下保证线程安全性。看看上述函数用到的queueInLoop函数
在这里插入图片描述

首先将cb加入函数队列,然后判断条件满足后进行weakup(),weakup()是怎么实现的呢?我们已经知道,在EventLoop中会调用poll(2)函数阻塞等待监听套接字的活动事件。EventLoop里面新增了几个成员:
在这里插入图片描述
添加了一个 wakeupFd_以及wakeupChannel_;我们只需要往wakeUpFd_里面写入一个字节,这样IO线程从IO mulitiplexing阻塞中调用被返回。而在EventLoop::loop()函数中添加了一行代码用于唤醒后执行其他线程的cb。
在这里插入图片描述
在这里插入图片描述
值得注意的是,functor这个vector不是在临界区依次调用Functor,而实把回调利厄表Swap()到局部变量中,一方面减少了临界区的长度,相当于直接清空原来的函数队列,这样不会影响到其他线程调用queueInLoop,另一方面也避免了死锁,因为Functor可能会再次调用queueInLoop()。这里设计的也非常巧妙,值得学习。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值