2017-09-15 4 views
6

Release과 달리 Debug 모드에서 MSVC를 사용하여 빌드 할 때 임의의 간격으로 다음 코드가 충돌합니다.MSVC의 디버그 모드에서 std :: future에 할당 할 때 크래시가 발생했습니다.

#include <future> 

using namespace std; 

int main() { 
    auto l = [](){}; 
    auto f = async(launch::async, l); 

    for (int i = 0; i < 1000000; ++i) 
     f = async(launch::async, l); 
} 

콘솔 출력 메시지 :

F는 \ DD \ vctools \ CRT \ crtw32 \ stdcpp \ THR \ mutex.c (51) 뮤텍스 파괴하면서이 바쁜

전체 호출 스택은 다음과 같습니다. https://pastebin.com/0g2ZF5C1

이제 분명히 스트레스 테스트 일 뿐이지 만 나는 완전히 바보 같이 행동하고 있습니까?

자료 공유 된 상태 *이

에 다른 내용을 이동이-할당 : operator= 말했다 것대로, 기존의 미래에 새로운 작업을 재 할당 괜찮아요 날 것으로 보인다 (http://en.cppreference.com/w/cpp/thread/future/operator%3D으로 인해).

MSVC의 런타임에 버그가 있습니까?

for (int i = 0; i < 1000000; ++i) { 
    f.wait(); 
    f = async(launch::async, l); 
} 

하지 operator= 그 자체는 wait를 호출하는 가정 :

놀랍게도 내가 수동 따라서으로 루프를 만들고, 할당하기 전에 대기()를 호출하면 프로그램이 충돌을 중지?

배경 :

_MSC_VER1911

코드가의 도움으로 지어진 같습니다 :

Microsoft Visual Studio Community 2017 Preview(2) 
Version 15.4.0 Preview 2.0 

그냥 새로운 C++ 프로젝트를 열었습니다.

+0

msvc 및 컴파일러의 정확한 버전이 유용 할 것입니다. – Yakk

+0

추측 : f를 재 지정하려고 할 때 'l'이 여전히 실행되는 경우가 있습니다.아마도 디버그에서 람다를 만드는 오버 헤드는 나머지 코드의 디버그 버전의 오버 헤드와 비교할 때 훨씬 큽니다. 디버그 버전에서만 발생한다고 설명 할 수 있습니다. –

+0

@Yakk 물론이 질문을 편집했습니다. –

답변

1

operator=wait이라고할까요?

나는 그것이로 가정인지 모르겠지만, <future>의 MSVC15.3.4 구현에서 피상적 인 눈이 강하게하지 않는 것이 좋습니다 것으로 보인다. wait 전화로보고

//User Code 
future f = /*...*/; 
f = /*...*/; //(1) 
//MSVC Code 
future& operator=(future&& _Right) _NOEXCEPT //(1) 
    { // assign from rvalue future object 
    _Mybase::operator=(_STD move(_Right)); //(2) 
    return (*this); 
    } 
_State_manager& operator=(_State_manager&& _Other) //(2) 
    { // assign from rvalue _Other 
    _Move_from(_Other); //(3) 
    return (*this); 
    } 
void _Move_from(_State_manager& _Other) //(3) 
    { // move stored associated asynchronous state object from _Other 
    if (this != _STD addressof(_Other)) 
     { // different, move 
     if (_Assoc_state) 
      _Assoc_state->_Release(); //(4) 
     _Assoc_state = _Other._Assoc_state; 
     _Other._Assoc_state = 0; 
     _Get_only_once = _Other._Get_only_once; 
     } 
    } 
void _Release() //(4) 
    { // decrement reference count and destroy when zero 
    if (_MT_DECR(_Refs) == 0) 
     _Delete_this(); //(5) 
    } 
void _Delete_this() //(5) 
    { // delete this object 
    if (_Deleter) 
     _Deleter->_Delete(this); //External Code 
    else 
     delete this; 
    } 

wait 문을 포함하는 더 좋을 수도, 일을 동기화하고 future 개체가 수정 될 안전 상태에 있는지 확인하는 데 도움이됩니다.

관련 문제