c++ - `std::async` 用于 C++ 中的异步回复
问题描述
概述:我有一个客户端-服务器实现,它使用 DBus( sdbus-c++ ) 向服务器发送异步请求。现在我的服务器与同步运行的硬件 API 进行交互,并且需要大量时间来生成回复。所以我有一个std::queue
at 服务器,它保存所有收到的异步请求,并一个一个地处理它们。处理完服务器后,以为发送的请求注册的回调的形式发回回复。
#client.h
class Client
{
Client();
~Client();
void sendRequestA()
{
... use DBus async call to send request to server
}
void sendRequestB() {...}
protected:
virtual void replyCallbackA(const uint8_t& status) = 0 ; // ... callback invoked by the DBus server
virtual void replyCallbackB(const uint8_t& status) = 0 ;
}
Ì 面临使用std::async
测试这个特定用例的问题。
#test.cpp
//std::future<void> gFuture;
class ClientTest : public Client
{
ClientTest();
~ClientTest();
std::future<void> m_future;
virtual void replyCallbackA(const uint8_t& status) override
{
std::cout<<"replyCallbackA status = "<< status<< "\n";
m_future.get();
//gFuture.get();
}
virtual void replyCallbackB(const uint8_t& status) override
{
std::cout<<"replyCallbackB status = "<< status<< "\n";
m_future.get();
//gFuture.get();
}
}
int main()
{
ClientTest cTest;
cTest.m_future = std::async(std::launch::async, &ClientTest::sendRequestA, &cTest);
cTest.m_future = std::async(std::launch::async, &ClientTest::sendRequestB, &cTest);
//gFuture = = std::async(std::launch::async, &ClientTest::sendRequestA, &cTest); -- no change in behavior with use of a global std::future.
}
我在这里的理解是,将调用sendRequestA
& sendRequestB
,并且还将调用回调函数。
但是,在这种情况下,调用&main
后立即退出,并且没有收到回调响应。sendRequestA
sendRequestB
编辑:我也尝试过使用全局变量 for std::future
,但行为是相同的。
谁能告诉我的理解有什么问题?
解决方案
std::async
返回一个以传递给的函数的返回值完成的未来std::async
。
对未来的第二次分配将阻塞,直到调用sendRequestA
完成(由于前一个std::future
实例的析构函数而阻塞)。它不会等到收到回复回调(除非你被阻止,sendRequestA
但这会很奇怪)。
m_future.get()
在您的回复回调将阻塞,直到未来解决(sendRequestA
返回)。但是,它已经发送(因为这是您获得回复的唯一方式),因此.get()
呼叫将立即返回。
我认为您想使用更像std::promise
. 在您的回复回调中,您将调用std::promise::set_value
以解决未来问题。调用与std::promise
or关联的未来的析构函数std::future::get
将阻塞直到std::promise::set_value
被调用(或承诺被销毁)。
推荐阅读
- swift - iOS - 使用泛型重用相同的 TableViewController
- shopify - 如何在 Shopify 风险主题上设置猫头鹰轮播?
- mysql - Mysql 排名高于函数
- javascript - 使用 codeigniter 将数据更新到 2 个表中
- r - 如果在使用 ifelse() 时在 R 中满足条件,则使用先前的值
- html - 如何使“剪辑路径”中的径向角看起来干净?
- maven - 如何为 Gradle 构建中的测试保留端口?
- sql - 组合两个 Teradata SQL 查询
- awk - 如果第一个字段的值匹配,则打印连续行
- c# - 标签具有前缀时无法获取请求值 Soap 请求