2017-03-07 15 views
5

Với mã nguồn saustd :: kỳ hạn và ngoại lệ

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

int main() { 

    auto task = std::async(std::launch::async, [] {  
     std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 
     throw std::runtime_error("error"); 
    }); 


    try { 
     while (task.wait_for(std::chrono::seconds(0)) !=std::future_status::ready) 
     { 
      std::cout << "Not ready: " << std::endl; 
     } 
     task.get(); 
    } 
    catch (const std::exception& e) 
    { 
     std::cout << "Valid: " << task.valid() << std::endl; 
    } 

} 

tôi mong đợi, rằng chương trình sẽ đáp ứng với Valid: 0. Sử dụng g ++ 6.2.0 đây là trường hợp. Tuy nhiên, sử dụng MS VS2015 Phiên bản 14.0.25431.01 Cập nhật 3 câu trả lời là Valid: 1. Trạng thái của tương lai không phải là không hợp lệ, sau khi ngoại lệ được truyền cho chủ đề chính. Đây có phải là một lỗi hoặc tôi đang chạy vào hành vi không xác định ở đây?

Trả lời

1

Tôi dường như là một lỗi.

Theo std::future::get documentation, valid() phải trả lại false sau khi gọi đến get.

Mọi trạng thái chia sẻ được phát hành. valid()false sau khi gọi đến phương thức này.

Đào một chút vào VC++ thực hiện get, có một lỗi đó:

virtual _Ty& _Get_value(bool _Get_only_once) 
     { // return the stored result or throw stored exception 
     unique_lock<mutex> _Lock(_Mtx); 
     if (_Get_only_once && _Retrieved) 
      _Throw_future_error(
       make_error_code(future_errc::future_already_retrieved)); 
     if (_Exception) 
      _Rethrow_future_exception(_Exception); 
     _Retrieved = true; 
     _Maybe_run_deferred_function(_Lock); 
     while (!_Ready) 
      _Cond.wait(_Lock); 
     if (_Exception) 
      _Rethrow_future_exception(_Exception); 
     return (_Result); 
     } 

về cơ bản, _Retreived nên cũng được thiết lập để true nếu _Exception giữ một exception_ptr. vào thời điểm ném, biến này không bao giờ được đặt. nó xuất hiện khi họ thử nghiệm nó, họ đã không thử nghiệm cho một tương lai sẵn sàng, chỉ cho tương lai không sẵn sàng, bởi vì sau này sẽ không hiển thị lỗi này.

+0

Có cách giải quyết khác không? Khi tôi loại bỏ câu lệnh wait_for nó hoạt động như mong đợi, nhưng trong mã sản xuất của tôi, tôi cần một luồng chương trình tương tự với nguồn mẫu. – IcePic

+0

@IcePic có thể sử dụng 'concurrency :: task' để thay thế. theo VC++, 'std :: async' là một trình bao bọc mỏng xung quanh các tác vụ. –

Các vấn đề liên quan