Visual studio 2012 对未来对象进行更改

Visual studio 2012 对未来对象进行更改,visual-studio-2012,c++11,Visual Studio 2012,C++11,我正在尝试根据用户输入更改未来对象的行为 #include <iostream> #include <future> //=======================================================================================! struct DoWork { DoWork(int cycles, int restTime) : _cycles(cycles), _restTime(rest

我正在尝试根据用户输入更改未来对象的行为

#include <iostream>
#include <future>

//=======================================================================================!
struct DoWork
{

    DoWork(int cycles, int restTime) : _cycles(cycles), _restTime(restTime), _stop(false)
    {
    }

    void operator () ()
    {
        for(int i = 0 ; i < _cycles; ++i)
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(_restTime));
            if(_stop)break;

            doTask();
        }
    }

    void stop()
    {
        _stop = true;
    }

private:
    void doTask()
    {
        std::cout << "doing task!" << std::endl;
    }

private:
    int _cycles;
    int _restTime;
    bool _stop;
};

//=======================================================================================!

int main()
{
    DoWork doObj(50, 500);
    std::future<int> f = std::async(std::launch::async, doObj);

    std::cout << "Should I stop work ?" << std::endl;
    std::cout << "('1' = Yes, '2' = no, 'any other' = maybe)" << std::endl;
    int answer;
    std::cin >> answer;

    if(answer == 1) doObj.stop();

    std::cout << f.get() << std::endl;
    return 0;
}
//=======================================================================================!
#包括
#包括
//=======================================================================================!
结构销钉
{
DoWork(整数周期,整数restTime):\u周期(周期),\u restTime(restTime),\u停止(假)
{
}
void运算符()()
{
对于(int i=0;i<_个周期;++i)
{
std::this_thread::sleep_for(std::chrono::毫秒(_restime));
如果(_停止)中断;
doTask();
}
}
无效停止()
{
_停止=真;
}
私人:
void doTask()
{

std::cout您有一些问题。首先,您的函数对象实际上没有返回
int
,因此
std::async
将返回
std::future
。您可以通过从
DoWork::operator()实际返回
int
来解决此问题
,或者将
async
的结果存储在
std::future
中,而不尝试打印它

其次,
std::async
复制其参数(如果它们不在引用包装器中),因此堆栈上的
doObj
不会是异步线程使用的
DoWork
的同一实例。您可以通过在引用包装器中传递
doObj
来纠正这一问题(std::launch::async,std::ref(doObj))

第三,主线程和异步线程同时访问
DoWork::\u stop
。这是一种数据竞争,意味着程序具有未定义的行为。解决方法是使用
std::mutex
保护对
\u stop
的访问,或者将其设置为
std::atomic

总的来说,程序应该如下所示:

#包括
#包括
//=======================================================================================!
结构销钉
{
DoWork(整数周期,整数restTime):\u周期(周期),\u restTime(restTime),\u停止(假)
{
}
int运算符()()
{
对于(int i=0;i<_个周期;++i)
{
std::this_thread::sleep_for(std::chrono::毫秒(_restime));
如果(_stop)返回42;
doTask();
}
返回13;
}
无效停止()
{
_停止=真;
}
私人:
void doTask()
{
标准::cout
#include <iostream>
#include <future>

//=======================================================================================!
struct DoWork
{
    DoWork(int cycles, int restTime) : _cycles(cycles), _restTime(restTime), _stop(false)
    {
    }

    int operator () ()
    {
        for(int i = 0 ; i < _cycles; ++i)
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(_restTime));
            if(_stop) return 42;

            doTask();
        }
        return 13;
    }

    void stop()
    {
        _stop = true;
    }

private:
    void doTask()
    {
        std::cout << "doing task!" << std::endl;
    }

private:
    int _cycles;
    int _restTime;
    std::atomic<bool> _stop;
};

//=======================================================================================!

int main()
{
    DoWork doObj(50, 500);
    std::future<int> f = std::async(std::launch::async, std::ref(doObj));

    std::cout << "Should I stop work ?" << std::endl;
    std::cout << "('1' = Yes, '2' = no, 'any other' = maybe)" << std::endl;
    int answer;
    std::cin >> answer;

    if(answer == 1) doObj.stop();

    std::cout << f.get() << std::endl;
}
//=======================================================================================!