使用 future<> 和 promise<> 进行消息传递?

Posted

技术标签:

【中文标题】使用 future<> 和 promise<> 进行消息传递?【英文标题】:Using future<> and promise<> for message passing? 【发布时间】:2020-05-28 18:38:20 【问题描述】:

我正在尝试编写一个简单的程序来通过 future 和 promise 传递消息,所以我了解它们是如何工作的。目的是将 10 个对象从产品传递给消费者。不幸的是,我遇到了编译问题。有谁知道我哪里出错了? 谢谢!

更新解决方案。

#include <iostream>
#include <thread>
#include <unistd.h>
#include <stdlib.h>
#include <future>
#include <functional>
#include <vector>
using namespace std;
using namespace std::chrono;

struct MSG 
  int val;
;

void consumer(vector<future<MSG>> *futv) 
  for (auto& p : *futv) 
    this_thread::sleep_for(millisecondsrand() % 25);
    MSG m = p.get();
    cout << m.val << endl;
  


void producer(vector<promise<MSG>> *promv) 
  MSG m = 0;

  for (auto& p : *promv) 
    this_thread::sleep_for(millisecondsrand() % 25);
    p.set_value(m);
    m.val++;
  



int main(int argc, char *argv[])

  vector<promise<MSG>> promv;
  vector<future<MSG>> futv;

  for (int i=0; i<10; i++) 
    promv.push_back(promise<MSG>());
    futv.push_back(promv[i].get_future());
  

  thread tp producer, &promv;
  thread tc consumer, &futv;

  tp.join();
  tc.join();

  return 0;

编译...,

g++ -lpthread -pedantic -Wall test84.cc && ./a.out
0
1
2
3
4
5
6
7
8
9

【问题讨论】:

你不能重用一个承诺。你只能通过 Promise 发送一个值。 【参考方案1】:

错误是由于future 只能可移动但不可复制

for (auto p : futv) - 这是从向量复制元素的尝试。 使用以下循环来引用向量元素:

for (auto&amp; p : futv) 或者 for (decltype(auto) p : futv)


一般来说,这个想法可以作为一种练习,但承诺/未来并不是为此而设计的。问题是您不能将数组的元素重用于另一次运行。所以在实际使用中,生产者-消费者队列是通过使用较低级别的原语来实现的:互斥体、条件变量、原子等。

【讨论】:

我尝试进行该更改,但无法解决编译问题。还有其他建议吗? 这是另一个错误。将指针传递给线程而不是引用或使用 std::ref 包装器。 我尝试了指针方法,但仍然遇到问题。我想我需要更多阅读编译器错误的经验... 我更新了代码以使用指针,但仍有问题。感谢任何建议 我看到你改成了指针,但是又改回了auto&amp;auto,所以你得到了第一个错误。修复两个而不是一个。【参考方案2】:

您可以使用condition_variable,在这种情况下,它比未来/承诺的实现要好。

例如,使用两个线程,产品和消费者,当产品“i”(产品元素)完成后,它将传递给消费者“i”,消费者“i”等待产品准备好,然后被消费。

future/promise 用于例如多个返回值线程。

如果你希望你的线程在不同的时间点返回多个值,那么只需在线程中传递多个 std::promise 对象并从它们关联的多个 std::future 对象中获取多个返回值。

【讨论】:

以上是关于使用 future<> 和 promise<> 进行消息传递?的主要内容,如果未能解决你的问题,请参考以下文章

不完整类型 'class std::future<int> 的无效使用

Flutter 类型“Future<dynamic>”不是“Stream<PostModel>”类型的子类型?

尝试在 Future<List> 上使用数组方法“折叠”来获取项目的总价格

使用队列会导致 asyncio 异常“将 Future <Future pending> 附加到不同的循环”

std::future<>::get 清空结果

Flutter SQFLITE:请解释一下工厂和这个数据类型 Future<List<Trail>> 是啥意思