多线程程序设计(九)——Future
本文摘要了《Java多线程设计模式》一书中提及的 Future 模式的适用场景,并针对书中例子(若干名称有微调)给出一份 C++ 参考实现及其 UML 逻辑图,也列出与之相关的模式。
◆ 适用场景
当前线程将某个函数调用委托给其它线程去完成,自己可以继续后面的处理。仅在需要结果时才去获取被委托的函数的执行结果。
◆ 解决方案
将委托的函数作为 std::async 的启动函数。在需要结果时,调用 std::async 的返回对象 future 的 get() 函数,即可获取被委托的函数的执行结果。
◆ 参考实现
例子模拟了用例向主机(Host)发送请求后,过一会儿再要求获取请求结果(Data)的过程。
class Data
{
    ...
    string
    get_content()
    {
        return __content__;
    }
};
class Host
{
    ...
    future<Data>
    request(int count, char c)
    {
        ...
        future<Data> f = std::async(launch::deferred | launch::async,
                                    [=]() -> Data {
                                        for (int i = 0; i < count; ++i)
                                            std::this_thread::sleep_for(milliseconds(100));
                                        return Data(count, c);
                                    });
        ...
        return f;
    }
};
std::async 使用 async 或 deferred 的启动策略,启动 lambda 匿名函数,需要的数据(Data)被封装在 future 中返回。
...
int
main(int argc, char * argv[])
{
    ...
    std::printf("main BEGIN\n");
    Host host;
    future<Data> f1(host.request(30, 'A'));
    future<Data> f2(host.request(40, 'B'));
    future<Data> f3(host.request(50, 'C'));
    std::printf("main other Job BEGIN\n");
    std::this_thread::sleep_for(milliseconds(2000));
    std::printf("main other Job END\n");
    Data data1 = f1.get();
    Data data2 = f2.get();
    Data data3 = f3.get();
    std::printf("data1 = %s\n", data1.get_content().c_str());
    std::printf("data2 = %s\n", data2.get_content().c_str());
    std::printf("data3 = %s\n", data3.get_content().c_str());
    std::printf("main END\n");
    ...
}
用例向主机(Host)发送 3 个请求后,自行忙着别的事情(用等待 2 秒来模拟)后,立即要求获取请求结果(Data)。
以下类图展现了代码主要逻辑结构,

以下顺序图展现了线程并发中的交互。

◆ 验证测试
笔者在实验环境一中编译代码(-std=c++11)成功后运行可执行文件,
$ g++ -std=c++11 -lpthread future.cpp
$ ./a.out
运行结果如下:
...
main BEGIN
   request(30, A) BEGIN
   request(30, A) END
   request(40, B) BEGIN
   request(40, B) END
   request(50, C) BEGIN
   request(50, C) END
main other Job BEGIN
main other Job END
    (waited a while here)
data1 = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
data2 = BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
data3 = CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
main END
Bye Future...
从输出过程可以看到,当用例执行完 other Job 后,虽然会主动获取结果,但仍然要等待几秒钟才会拿到 data 1~3 的内容。
◆ 相关模式
- Future 模式可用于 Thread-Per-Message 中,当想要获取处理结果时。
 - Future 模式可用于 Worker Thread 中,当想要获取处理结果时。
 
◆ 最后
完整的代码请参考 [gitee] cnblogs/18842152 。更多模式请参考多线程程序设计。
致《Java多线程设计模式》的作者结城浩。写作中也参考了《C++并发编程实战》中的若干建议,致作者 Anthony Williams 和译者周全等。
受限于作者的水平,读者如发现有任何错误或有疑问之处,请追加评论或发邮件联系 green-pi@qq.com。作者将在收到意见后的第一时间里予以回复。 本文来自博客园,作者:green-cnblogs,转载请注明原文链接:https://www.cnblogs.com/green-cnblogs/p/18842152 谢谢!
                    
                
                
            
        
浙公网安备 33010602011771号