2016-07-02 3 views
0

Я хочу построить объект Delay асинхронно, а затем (из другого потока) повторно вызывает функцию foo с этого объекта.вызов std :: future :: get again

struct Delay { 
    Delay(int d) { 
     sleep(d); 
    } 
    void foo() { } 
}; 

struct Test { 
    Test() { 
     x = async(std::launch::async, 
        [&]() {return std::make_unique<Delay>(4);}); 
    } 
    void run() { x.get()->foo(); } 
    std::future<std::unique_ptr<Delay>> x; 
}; 

int main() { 
    auto t = Test(); 
    // do other stuff... 
    t.run(); 
    t.run(); // throwing an instance of 'std::future_error', "No associated state" 
    return 0; 
} 

Однако, очевидно, что второй раз, когда вызывается вызов x.get(), генерируется исключение.

Каков рекомендуемый способ справиться с такой ситуацией? Использование флага, как показано ниже, похоже на взлома. Есть ли способ лучше?

bool is_set = false; 
std::unique_ptr<Delay> ptr; 
void run_ptr() { 
    if (!is_set) { 
     ptr = x.get(); 
     is_set = true; 
    } 
    ptr->out(); 
} 

ответ

1

std::shared_future - рекомендуемый способ справиться с такой ситуацией.

Он может быть построен путем перехода от будущего и поддерживает несколько считывателей его состояния. Это отдельный объект, потому что одноразовое будущее имеет определенные улучшения в производительности, и потому, что это так тривиально, чтобы сделать совместное будущее, если оно вам понадобится.

Просто измените тип x на shared_future<std::unique_ptr<Delay>>, и все готово.

Обратите внимание, что в вашем вышеуказанном случае слой unique_ptr в основном бессмыслен. Наверное, в вашей реальной проблеме это не так.

Смежные вопросы