使用std::future监控线程执行类成员函数(c++)? [复制]

Posted

技术标签:

【中文标题】使用std::future监控线程执行类成员函数(c++)? [复制]【英文标题】:Use std::future to monitor and control thread executing class member function (c++)? [duplicate] 【发布时间】:2015-01-26 19:57:55 【问题描述】:

在此处使用信息:How to check if a thread is still running 我正在尝试在 std::future 中使用 lambda function 在专用 thread 中调用类 member function,以便可以监视 std::future 的完成情况使用future.wait_for()的线程状态

TestClass 创建一个std::future 并在其构造函数中启动一个线程。目的是允许其他成员函数监视进度并在必要时终止该线程。

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

class TestClass

public:
TestClass(const int &np) : nap(np), run(true)
       
    //Run member function in a thread, crucially be able to monitor the  thread status using the future;
    function = std::bind(&TestClass::Snooze, this, std::placeholders::_1, std::placeholders::_2);
    future = std::async(std::launch::async, [this] 
        function(nap, &run);
        return true;
    );




~TestClass()

//If future thread is still executing then terminate it by setting run = false
//Use wait_for() with zero milliseconds to check thread status.
auto status = future.wait_for(std::chrono::milliseconds(1));//needs to have a value > 0
if (status != std::future_status::ready)//execution not complete

    run = false;//terminate Snooze
    future.wait();//wait for execution to complete

std::cout << "TestClass: Destructor Completed" << std::endl;


void Snooze(const int &napLen, std::atomic<bool>* ptrRun)

while (*ptrRun)//check ok to to loop on.

std::cout << "zzzz...." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(napLen));//take a nap

std::cout << "TestClass: Finished Snoozing." << std::endl;


//Getter
bool isThreadFinished() const

auto status = future.wait_for(std::chrono::milliseconds(0));
if (status == std::future_status::ready)//execution complete

    return true;

else
 
    return false;
   


//Setter
void stopSnooze()

run = false;
std::cout << "TestClass: stopSnooze(): run = " << run << std::endl;


private:
int nap;
std::function<void(int, std::atomic<bool>*)> function;
std::future<bool> future;
std::atomic<bool> run;
;



int main()     

TestClass tc(1);//should see some zzzz's here
std::this_thread::sleep_for(std::chrono::seconds(5));

tc.stopSnooze();//demonstrate stopping the thread by setting run = false

std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "TestClass: Next test." << std::endl;

TestClass tc1(1);//should see some zzzz's here
std::this_thread::sleep_for(std::chrono::seconds(5));

编辑:更正代码以按预期运行。

【问题讨论】:

在其作用域结束之前销毁自动对象(main 中的tc)并不能阻止它在作用域结束时再次被销毁,这当然会导致未定义的行为。这也有点奇怪 - 虽然不是不正确 - 您将参数传递给 Snooze 而它可以简单地从对象中检索它们。 【参考方案1】:

我认为这是重复的,但实际上你只是打错了:

auto function = std::bind(&TestClass::Snooze, this, nap, &run);
auto future = std::async(std::launch::async, [&function]
    function();
    return true;
); 

应该是:

function = std::bind(&TestClass::Snooze, this, nap, &run);
future = std::async(std::launch::async, [this] 
    function();
    return true;
); 

您想分配给您的成员,而不是创建临时人员。照原样,您的构造函数是blocking on the future destructor。

【讨论】:

试过你的修改,但智能感知不喜欢:future = std::async(std::launch::async, [this] function(); return true; );我正在使用 Visual Studio 2013。 @GoFaster 在未来,“不喜欢”不再是有意义的信息。您应该提供实际错误是什么。在这种情况下,您需要将nap&amp;run 传递给function();

以上是关于使用std::future监控线程执行类成员函数(c++)? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

c++中的异步编程——future,promise

C++11 多线程 asyncfuturepackaged_taskpromise

[C++11 多线程异步] --- std::promise/std::future

[C++11 多线程异步] --- std::promise/std::future

[C++11 多线程异步] --- std::promise/std::future

[C++11 多线程异步] --- std::promise/std::future