多线程程序设计(九)——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号