c++ 多次使用promise

ecbunoof  于 2022-11-27  发布在  其他
关注(0)|答案(1)|浏览(230)

我尝试使用std::promise在单独的线程上向函数发送信号

class MyClass {
  std::promise<void> exitSignal;
  std::thread monitorThread;
}

void MyClass::start() {
  exitSignal = std::promise<void>();
  std::future<void> futureObj = exitSignal.get_future();
  monitorThread = std::thread(&MyClass::monitorFunction, this, std::move(futureObj));
}

void MyClass::stop() {
  exitSignal.set_value();
  if (monitorThread.joinable()) {
    monitorThread.join();
  }
}

void MyClass::monitorFunction(std::future<void> futureObj) {
  while (futureObj.wait_for(std::chrono::seconds(1)) == std::future_status::timeout) {
      // do stuff
  }
}

它运行良好,直到我尝试第二次调用start。然后我得到一个错误

std::future_error: Promise already satisfied

为什么呢?我每次开始都刷新承诺,未来似乎是有效的...

wqnecbli

wqnecbli1#

我将回应@Homer512的评论,并建议您调用stop()两次。我用您的代码做了一个小测试:

#include <future>
#include <thread>
#include <iostream>
#include <chrono>

struct MyClass
{
    std::promise<void> exitSignal;
    std::thread monitorThread;

    void start();
    void stop();
    void monitorFunction(std::future<void> futureObj);
};

void MyClass::start()
{
    exitSignal = std::promise<void>();
    std::future<void> futureObj = exitSignal.get_future();
    monitorThread = std::thread(&MyClass::monitorFunction, this, std::move(futureObj));
}

void MyClass::stop()
{
    exitSignal.set_value();
    if (monitorThread.joinable())
    {
        monitorThread.join();
    }
}

void MyClass::monitorFunction(std::future<void> futureObj)
{
    while (futureObj.wait_for(std::chrono::seconds(1)) == std::future_status::timeout)
    {
        std::cout << "Bla\n";
    }
}

int main()
{
    MyClass myc;
    std::cout << "Start 1\n";
    myc.start();
    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::cout << "Stop 1\n";
    myc.stop();
//    myc.stop(); // <- Boom!

    std::cout << "Wait\n";
    std::this_thread::sleep_for(std::chrono::seconds(3));

    std::cout << "Start 2\n";
    myc.start();
    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::cout << "Stop 2\n";
    myc.stop();
}

当我按原样运行时(第二个stop被注解掉),它运行时没有任何问题:

Start 1
Bla
Bla
Stop 1
Wait
Start 2
Bla
Bla
Stop 2

但如果放入第二个stop,则会遇到异常:

terminate called after throwing an instance of 'std::future_error'
  what():  std::future_error: Promise already satisfied
Aborted

相关问题