多线程程序设计(十)——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 谢谢!
                    
                
                
            
        
浙公网安备 33010602011771号