【BOOST C++ 13 并行编程】(4) Futures和 Promises线程
admin
2024-04-09 12:33:06
0

一、说明

        Futures 和 Promises 是将数据从一个线程传递到另一个线程的工具。虽然这也可以通过其他功能来完成,例如全局变量、futures 和 promises 在没有它们的情况下也能工作。此外,您不需要自己处理同步。

        未来是一个从另一个线程接收值的变量。如果您访问未来以获取值,您可能需要等到其他线程提供该值。 Boost.Thread 提供 boost::future 来定义未来。该类定义了一个成员函数 get() 来获取值。 get() 是一个阻塞函数,可能需要等待另一个线程。

        要在未来设置一个值,您需要使用一个承诺,因为 boost::future 不提供成员函数来设置一个值。

二、示例

        Boost.Thread 提供类 boost::promise,它有一个成员函数 set_value()。您总是将 future 和 promise 成对使用。您可以使用 get_future() 从承诺中获得未来。您可以在不同的线程中使用未来和承诺。如果在一个线程中的 promise 中设置了一个值,则可以在另一个线程中从 future 中获取它。

        示例 44.14。使用 boost::future 和 boost::promise

#define BOOST_THREAD_PROVIDES_FUTURE
#include 
#include 
#include 
#include void accumulate(boost::promise &p)
{int sum = 0;for (int i = 0; i < 5; ++i)sum += i;p.set_value(sum);
}int main()
{boost::promise p;boost::future f = p.get_future();boost::thread t{accumulate, std::ref(p)};std::cout << f.get() << '\n';
}

Example 44.14

        示例使用未来和承诺。未来 f 是从承诺 p 中接收到的。然后将对 promise 的引用传递给执行 accumulate() 函数的线程 t。 accumulate() 计算 0 到 5 之间所有数字的总和并将其保存在 promise 中。在 main() get() 中调用 future 将总数写入标准输出。

        未来 f 和承诺 p 是相关联的。当对未来调用 get() 时,将返回使用 set_value() 存储在承诺中的值。因为该示例使用两个线程,所以可能会在 accumulate() 调用 set_value() 之前在 main() 中调用 get()。在这种情况下,get() 会阻塞,直到使用 set_value() 将一个值存储在 promise 中。

        示例 44.14 显示 10。

        accumulate() 必须调整为在线程中执行。它必须采用 boost::promise 类型的参数并将结果存储在其中。示例 44.15 引入了 boost::packaged_task,这是一个将值从任何函数转发到未来的类,只要该函数通过 return 返回结果即可。

        示例 44.15。使用 boost::packaged_task

#define BOOST_THREAD_PROVIDES_FUTURE
#include 
#include 
#include 
#include int accumulate()
{int sum = 0;for (int i = 0; i < 5; ++i)sum += i;return sum;
}int main()
{boost::packaged_task task{accumulate};boost::future f = task.get_future();boost::thread t{std::move(task)};std::cout << f.get() << '\n';
}

Example 44.15

        示例 44.15 与前一个类似,但这次没有使用 boost::promise。相反,此示例使用类 boost::packaged_task,它与 boost::promise 一样提供返回未来的成员函数 get_future()。

        boost::packaged_task 的构造函数期望将在线程中执行的函数作为参数,但 boost::packaged_task 本身并不启动线程。必须将类型为 boost::packaged_task 的对象传递给 boost::thread 的构造函数,以便在新线程中执行该函数。

        boost::packaged_task 的优点是它在未来存储函数的返回值。你不需要调整一个函数来在未来存储它的值。 boost::packaged_task 可以看作是一个适配器,它可以存储未来任何函数的返回值。

        虽然该示例摆脱了 boost::promise,但以下示例也没有使用 boost::packaged_task 和 boost::thread。

        示例 44.16。使用 boost::async()

#define BOOST_THREAD_PROVIDES_FUTURE
#include 
#include 
#include int accumulate()
{int sum = 0;for (int i = 0; i < 5; ++i)sum += i;return sum;
}int main()
{boost::future f = boost::async(accumulate);std::cout << f.get() << '\n';
}

        在示例 44.16 中,accumulate() 被传递给函数 boost::async()。这个函数统一了 boost::packaged_task 和 boost::thread。它在新线程中启动 accumulate() 并返回未来。

        可以将启动策略传递给 boost::async()。这个附加参数决定了 boost::async() 是在新线程中还是在当前线程中执行该函数。如果您传递 boost::launch::async,boost::async() 将启动一个新线程;这是默认行为。如果您传递 boost::launch::deferred,该函数将在调用 get() 时在当前线程中执行。

        尽管 Boost 1.56.0 允许将 boost::launch::async 或 boost::launch::deferred 传递给 boost::async(),但尚未实现在当前线程中执行函数。如果您传递 boost::launch::deferred,程序将终止。

相关内容

热门资讯

爱上海|汇龙潭公园即将免费开放... 汇龙潭公园作为嘉定重要的公共生态空间,以其清幽雅致的环境承载着市民对自然生活的向往。近年来,市民热切...
凤香老酒在太白 太白酒品牌战略... 5月9日,以“立心志,换新天”为主题的太白酒品牌战略与新品上市联谊会在西安隆重召开。太白酒业第一责任...
原创 立... 白瓷盘里层层叠叠的晶莹,像夏日荷塘里亭亭玉立的绿意。冬瓜肉末蒸粉丝这道菜,总让我想起江南水乡的烟雨朦...
莲藕焖五花肉:家常美味制作攻略... 在家聚餐的时候,总想准备一道既下饭又有面子的菜,今天就来聊聊莲藕焖五花肉。这道菜色泽诱人,鲜香四溢,...
【甘快看】“世界第一古梨园”迎... 人间四月芳菲盛,万亩梨花雪漫天。近日,被誉为“世界第一古梨园”的兰州市皋兰县什川古梨园迎来客流高峰,...
大邑开展特种设备安全综合检查 为统筹推进西岭雪山景区复工复产与“五一”假日旅游安全保障工作,近日,四川省大邑县市场监管局联合县文体...
原创 苗... 刷到苗苗的最新vlog,我不禁为这位新晋三胎妈妈的生活感到惊叹。她与助理来了一场速度惊人的韩国之旅,...
原创 适... “从手到口,从口到心,中国人延续着对世界和人生特有的感知方式。只要点起炉火,端起碗筷,每个平凡的人,...
黑龙江丰林:杜鹃花海引游人 “... 来源:中国新闻网中新网伊春5月10日电(记者 刘璐)10日,“浪漫林都·春赏杜鹃”第二届伊春·丰林杜...
原创 天... 天津美食如同一幅绚丽多彩的饮食画卷,其品种之丰富令人叹为观止。河海两鲜与飞禽野味在此交相辉映,这正与...
用土灶烟火链动文旅消费 “金山... 5月10日上午,上海山阳田园内炊烟升腾,香气四溢,“金山家宴·由我掌厨”上海湾区首届厨神挑战赛热烈开...
拉萨市民乐享“过林卡”时光 5月10日,初夏时节,西藏罗布林卡内绿意盎然,风景如画。罗布林卡藏语意为“宝贝园林”,始建于公元十八...
黑龙江丰林:杜鹃花海引游人 “... 中新网伊春5月10日电(记者 刘璐)10日,“浪漫林都·春赏杜鹃”第二届伊春·丰林杜鹃花观赏季活动在...
博爱旅游景点有哪些必玩推荐及深... 2025年4月11日,我站在博爱县靳家岭的观景台上,原本计划拍摄太行山春日的层峦叠翠,却猝不及防地撞...
广州莲花山“蒂王争霸赛”高能不... 5月10日,广州番禺莲花山景区内,一株由景区自主培育的并蒂同心睡莲进入开花第二天,花色由初开时的淡蓝...
控糖又清肠,奇亚籽柠檬水这样做... 最近我每天早上喝一杯奇亚籽柠檬水, 肚子没那么胀了,嘴也没那么馋了。 它不是减肥水,但是真的特别解腻...