Channel Class详解&源码阅读

Channel Class源码阅读

欢迎交流!!!

Channel Class封装关心的文件描述符、关心的事件和对应的处理函数。该对象的实例只能在所属的EventLoop中被调用,所以不需要考虑线程安全问题。

数据成员

  • loop_

该对象的实例所在的EventLoop

  • fd_

该对象关心的文件描述符

  • events_

该对象关心的事件

  • revents_

触发的事件

  • index_

标识,标定当前channel处于 未 被 监 视 、 不 关 心 事 件 , 被 监 视 未被监视、不关心事件,被监视 的状态。

  • logHup_

这是干嘛的?

  • std::weak_ptr<void> tie_

拥有该Channel的对象。问题来了,poller那边明确提出,它及其派生类EPollPollerPollPoller均不拥有Channel,那谁拥有Channel呢?

  • bool tied_

当前Channel是否被拥有

  • evntHandling_

当前Channel是否有事件正被处理

  • addedToLoop_

当前Channel是否被监视

  • ReadEventCallback readCallback_; EventCallback writeCallback_; EventCallback closeCallback_; EventCallback errorCallback_;

读/写/断/错相应的处理函数

函数成员

  • Channel(EventLoop* loop, int fd)

构造函数,对数据成员执行初始化

  • void enableReading() { events_ |= kReadEvent; update(); } void disableReading() { events_ &= ~kReadEvent; update(); } void enableWriting() { events_ |= kWriteEvent; update(); } void disableWriting() { events_ &= ~kWriteEvent; update(); } void disableAll() { events_ = kNoneEvent; update(); } bool isWriting() const { return events_ & kWriteEvent; } bool isReading() const { return events_ & kReadEvent; }

设置or关闭关心的事件,或者确定事件是否有被关心

  • void setReadCallback(ReadEventCallback cb) { readCallback_ = std::move(cb); } void setWriteCallback(EventCallback cb) { writeCallback_ = std::move(cb); } void setCloseCallback(EventCallback cb) { closeCallback_ = std::move(cb); } void setErrorCallback(EventCallback cb) { errorCallback_ = std::move(cb); }

设置相应的事件处理函数,但是move的功能我不太懂

  • void handleEvent(Timestamp receiveTime);

根据发生的事件调用响应的事件处理函数(void handleEventWithGuard(Timestamp receiveTime)),在调用前要检查是否绑定到某一个对象上。

  • void tie(const std::shared_ptr<void>&)

将当前Channel绑定到一个对象上

  • bool isNoneEvent() const { return events_ == kNoneEvent; }

Poller Class那边时常提起的Channel::isNoneEvent()的判断依据是Channel::events_,即没有关心的事件。

  • void update()

调用EventLoopupdate(),然后再去调用Poller Classupdate()(可能不叫这个名字)

  • void remove()

调用EventLoopremove(),然后再去调用Poller Classremove()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言中的channel实现是通过一个称为&quot;管道&quot;(pipe)的数据结构来实现的。在go/src/runtime/chan.go文件中,定义了channel的数据结构: ```go type hchan struct { qcount uint // 队列中的元素数量 dataqsiz uint // 环形缓冲区大小 buf unsafe.Pointer // 指向环形缓冲区的指针 elemsize uint16 // 元素大小 closed uint32 // 是否已关闭 elemtype *_type // 元素类型 sendx uint // 发送位置 recvx uint // 接收位置 recvq waitq // 接收队列 sendq waitq // 发送队列 lock mutex // 互斥锁 } ``` 其中,qcount记录了当前channel中的元素个数,dataqsiz表示channel的缓冲区大小,buf指向channel的环形缓冲区,elemsize表示一个元素的大小,closed表示channel是否已关闭,elemtype表示channel中元素的类型,sendx表示下一个写入位置,recvx表示下一个读取位置,recvq和sendq分别表示等待读取和等待写入的goroutine队列,lock是保护channel的互斥锁。 在channel的实现中,有以下几个重要的函数: - chanmake:创建一个新的channel。 - chanclose:关闭一个channel。 - chansend:向一个channel中写入数据。 - chanrecv:从一个channel中读取数据。 - chanselect:可以同时等待多个channel的读写操作。 Go语言中的channel实现是基于CSP(Communicating sequential processes)模型的,通过channel进行协程之间的通信,实现了协程之间的同步。在底层实现中,channel通过互斥锁和条件变量来保证并发安全。当有多个goroutine同时读写channel时,会使用等待队列来避免busy waiting,提高了并发效率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值