多线程程序设计(十)——Two-Phase Termination
本文摘要了《Java多线程设计模式》一书中提及的 Two-Phase Termination 模式的适用场景,并针对书中例子(若干名称有微调)给出一份 C++ 参考实现及其 UML 逻辑图,也列出与之相关的模式。
◆ 适用场景
保证线程接收到了终止请求后,能够尽快并安全地终止线程。
◆ 解决方案
定义一个标志位,表示是否终止线程;在线程执行具体任务前,先判断是否要终止当前工作。
◆ 参考实现
例子模拟了一个计数器(Countup)从启动到被要求停止的整个过程。计数的过程中收到停止请求后,没有立即停止,而是先执行了收尾输出工作,最后才停下来。
class Countup
{
...
atomic_bool
__shutdownrequested__; #1
...
void
shutdown()
{
__shutdownrequested__.store(true, memory_order_release);
}
void
run()
{
while (!__shutdownrequested__.load(memory_order_acquire)) { #2
++__counter__;
std::printf("\tWorking: count = %ld\n", __counter__);
std::this_thread::sleep_for(milliseconds(500));
}
std::printf("\tEnding: count = %ld\n", __counter__); #3
std::printf("\tShutdown\n");
}
};
Countup 的停止标志位 __shutdownrequested__,用于判断是否接受到了停止的请求(#1)。Countup::run() 是计时开始的入口函数,每隔 0.5 秒会判断是否收到停止请求。如停止标志位指示不停止计数,计数器就继续计数;当停止标志位指示停止计数,就退出计数(#2)。在结束计数前的收尾工作中,会输出最终的计数结果(#3)。
int
main(int argc, char * argv[])
{
...
Countup c;
thread t(&Countup::run, &c);
std::this_thread::sleep_for(milliseconds(10000));
std::printf("main shutdown requested\n");
c.shutdown(); #1
std::printf("main join\n");
t.join();
std::printf("main END\n");
...
}
主程序启动计数器,在 10 秒钟之后向其发出停止的请求(#1),并等待计数器结束。
以下类图展现了代码主要逻辑结构,
以下顺序图展现了线程并发中的交互。
◆ 验证测试
笔者在实验环境一中编译代码(-std=c++11)成功后运行可执行文件,
$ g++ -std=c++11 -lpthread two-phase_termination.cpp
$ ./a.out
运行结果如下:
...
main BEGIN
Working: count = 1
Working: count = 2
...
Working: count = 19
Working: count = 20
main shutdown requested
main join
Ending: count = 20
Shutdown
main END
...
从输出过程可以看到,当主线程向计数器线程发出停止的请求后,计数器先完成了收尾的输出工作,最后计数器和主线程分别结束。
◆ 相关模式
- 进行终止处理时,为了禁止其他操作,可使用 Balking 模式。
◆ 最后
完整的代码请参考 [gitee] cnblogs/18853368 。更多模式请参考多线程程序设计。
致《Java多线程设计模式》的作者结城浩。写作中也参考了《C++并发编程实战》中的若干建议,致作者 Anthony Williams 和译者周全等。
受限于作者的水平,读者如发现有任何错误或有疑问之处,请追加评论或发邮件联系 green-pi@qq.com。作者将在收到意见后的第一时间里予以回复。 本文来自博客园,作者:green-cnblogs,转载请注明原文链接:https://www.cnblogs.com/green-cnblogs/p/18853368 谢谢!
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】开源 Linux 服务器运维管理面板 1Panel V2 版本正式发布
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 这5种规则引擎,真香!
· 基于.net6的一款开源的低代码、权限、工作流、动态接口平台
· 【好用推荐】免费在线图片压缩工具,附源码
· 纯C#软实现openGL(V0.1),黑盒变白盒
· Claude Code 初体验 - Windows