Monthly Read Posts in Dec 2018
Programming Languages
这篇 post 总结起来就是深入浅出。
The importance of knowing STL algorithms
能熟练运用 STL algorithms 是一个 experienced c++ programmer 的基本要求。
另外里面提到了使用 algorithms 的两个 pitfalls,其中一个是滥用 for_each()
,这个确实有点意思。
这篇 post 总结起来就是深入浅出。
The importance of knowing STL algorithms
能熟练运用 STL algorithms 是一个 experienced c++ programmer 的基本要求。
另外里面提到了使用 algorithms 的两个 pitfalls,其中一个是滥用 for_each()
,这个确实有点意思。
原本的计划是今天给 ezio 加上 SIGINT 的处理:自动退出运行的 EventLoop
,让程序自主正常退出;但是在实现 Windows 版本的过程中发现了一些问题,最后思考再三,决定放弃整个特性。
至此,我们整个系列宣告完结。
现在回过头往前看,是不是觉得其实这些底层的东西也没这么难?有时候只是需要一些基础和解决问题的方法罢了。
Rant:做业务才真的难呢,框架和流程都给你定死了,一坨又一坨用了几年的不明觉厉的封装,如果内部文档哪个不详,又没有熟悉的人带着你,基本就净在里面绕圈子了。
有了前面的铺垫我们终于可以开始实现我们的主角 ActiveThread 了,虽然它登场的有点晚。
这个系列的开头我们提到 ActiveThread
有两个鲜明的特点:
ActiveThread
内部运行一个 message-loop,方便持续的执行我们提交的任务这两点和 Android 原生提供的 HandlerThread
是一模一样的。
不过和 HandlerThread
不同,我们这里不打算采用继承 Thread
的方式,而是采用 composition。原因之一是我个人非常反感传统的 OO 继承手法;并且 Java 8 开始正式支持 lambda 之后,不用继承我们的工作也可以做得很好。
不适用继承同时有个好处,我们可以只暴露我们需要的接口,避免误用(比如经典的用 run()
而不是 start()
)
前面我们实现了 MessageLoop
,现在该轮到 TaskRunner
了。
在我们的设计中,TaskRunner
的定位是类似 Handler
,用来驱动/使用 MessageLoop
,将 MessageLoop
隐藏在日常使用中。
有了 MessagePumpDefault
之后,我们就可以开始着手实现最核心的 MessageLoop
了。
不过在此之前,我们还首先需要实现一个辅助设施:PendingTask
。
一个 PendingTask
instance 表示一个等待被执行的 task,并且这个 task 可能是一个 delayed task。
因此 PendingTask
需要能够表示时序上的顺序,这个可以利用 Instant
类型的一个时间戳,结合一个 long
类型的 sequence-number。因为有可能两个 delayed tasks 的时间戳相同,此时就必须要用 seq-num 来区分先后顺序。
另外,PendingTask
为了能够表示 task 语义,他必须可以被执行。这可以通过内部存储一个 Runnable
或者 Callable
成员做到。
我们的实现选择 Runnable
,因为
PostTaskAndReplyWithResult()
来组合两个函数;或者更一般的,使用 continuation 来 lifting restrictions1 | class PendingTask { |
我们使用了 AtomicLong
来存储当前的 sequence-number,因为我们不知道某个 PendingTask
会在哪个线程上被创建。