这是我参与8月更文挑战的第19天,活动详情查看:8月更文挑战
单线程并发设计
前文已经讨论了单线程并发与多线程并发的关系,同时也讨论了单线程并发的优点和需要面临的挑战。最后我们提到了单线程并发的事件循环模式和线程循环模式。本文将继续探讨单线程并发的线程循环模式设计。
线程循环
大多数长时间运行的应用程序应该在某种循环中执行,其中主应用程序等待来自外部的输入,并处理该输入后返回等待。这种线程循环服务于各种应用程序,有时是隐藏的,而有时是可见的。
代理商
线程循环通常调用一些执行任务的组件,可以称为代理中间件。代理的生命周期可能会有所不同。代理人可以:
- 在应用程序的整个生命周期内运行。
- 运行更长时间运行的作业 - 最终完成。
- 运行一次性任务 - 很快完成。
线程循环呼叫代理
线程通过循环呼叫代理,将程序任务转交给代理进行执行。线程循环负责循环(重复调用代理)并检测代理何时终止,从而终止线程循环。代理负责执行应用程序逻辑本身,而不是循环。
代理可以调用其他代理
代理可以通过调用其他代理进行任务的执行,不同的代理具备不同的等级及对应的责任。
单线程任务切换
为了能够看似同时在多个任务上取得进展,在任务上取得进展的线程必须能够在任务之间切换。而这就是任务切换。当只有一个可用线程时,则需要通过代码设计使任务切换成为可能。为了使任务能够在单线程进行切换,每个任务必须拆分为一个或多个增量子任务。当代理被调用时,会执行增量子任务。
增量大小平衡
如果单个线程要能够在多个任务之间切换,那么这些任务不能分成太大的增量是必要的。换句话说,帮助确保在任务之间公平分配执行时间是每个任务的责任。正确的大小究竟是多少,取决于具体的任务需求。
优先执行
可以使部分任务优先于其他任务进行执行,通过对代理传递一个额外的参数来控制任务执行的顺序。
扩展单线程并发
如果应用程序中只有一个线程在执行,则不能利用多个 CPU。解决方案是启动多个线程。通常,每个cpu都有至少一个线程 - 取决于您的线程需要执行的任务类型。如果有需要执行阻塞 IO 工作的任务,例如从文件系统或网络读取,那么每个 CPU 可能需要多个线程。每个线程在等待阻塞 IO 操作完成时将被阻塞,什么也不做。
后记
- 千古兴亡多少事?悠悠。不尽长江滚滚流。