【问题标题】:`std::async` for asynchronous replies in C++`std::async` 用于 C++ 中的异步回复
【发布时间】:2021-05-18 17:07:26
【问题描述】:

概述: 我有一个客户端-服务器实现,它使用 DBus(sdbus-c++) 向服务器发送异步请求。现在我的服务器与同步运行的硬件 API 进行交互,并且需要大量时间来生成回复。所以我在服务器上有一个std::queue,它保存了所有收到的异步请求,并一个一个地处理它们。处理完服务器后,以为发送的请求注册的回调的形式发回回复。

#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.
}

我的理解是 sendRequestAsendRequestB 将被调用,并且回调函数也将被调用。
但是这种情况下,main在调用sendRequestA&sendRequestB后立即退出,并没有收到回调响应。

编辑:我也尝试为std::future 使用全局变量,但行为相同。

谁能告诉我我的理解哪里出了问题?

【问题讨论】:

    标签: c++ asynchronous dbus stdasync


    【解决方案1】:

    std::async 返回一个以传递给std::async 的函数的返回值完成的未来。

    对未来的第二次分配将阻塞,直到对 sendRequestA 的调用完成(由于前一个 std::future 实例的析构函数而阻塞)。它不会等到收到回复回调(除非您在 sendRequestA 中阻止,但这会很奇怪)。

    您的回复回调中的m_future.get() 将阻塞,直到未来解决(sendRequestA 返回)。但是,它已经发送了(因为这是您获得回复的唯一方式),因此.get() 调用将立即返回。

    我认为你想使用更像std::promise 的东西。在您的回复回调中,您将致电std::promise::set_value 来解决未来问题。调用与std::promisestd::future::get 关联的未来析构函数将阻塞,直到调用std::promise::set_value(或promise 被销毁)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-29
      • 1970-01-01
      • 1970-01-01
      • 2020-10-28
      • 2018-11-19
      相关资源
      最近更新 更多