2009-08-21 2 views
2

내 질문에 간략한 버전 :부스트 : 스레드가 충돌 함 Microsoft C++ 컴파일러

이 코드는 컴파일러를 충돌시킵니다.

pThread[0] = new boost::thread(
boost::bind(
    &cGridAnimator::DoJob, // member function 
     this),     // instance of class 
     0);     // job number 

이 코드를 컴파일 할 때 컴파일러가 충돌합니다. (이 코드를 실행할 때 나는 내 프로그램이 아닙니다!)

무엇을 고쳐야합니까? 8 코어 시스템을 활용하기 위해 질문

내가 8 개 별도의 작업에 큰 3D 그리드에서 일을 분할하고의


롱 버전은 별도의 스레드에서 실행된다.

이 완벽하게 작동합니다 :

JOB_LOOP { 
     pThread[kjob] = new boost::thread(::DoJob, kjob); 
    } 

글로벌 무료 함수 DoJob은 작업의 수에 따라, cGridAnimator의 전역 인스턴스에서 데이터를 읽습니다.

그러나 이러한 전역 변수가 주위에 떠 다니는 것을 좋아하지 않으며 필요한 데이터를 얻는 데 너무 많은 접근 자 메서드를 사용하지 않아도됩니다. cGridAnimator 메서드를 사용하는 것이 훨씬 더 정돈 된 방법입니다.

따라서이 질문의 맨 위에있는 코드.

그러나 MSVC++ 2008에서 컴파일하면 컴파일러에서 다음 불만 사항을 발행 한 다음 충돌합니다.

1>Compiling... 
1>mfm1.cpp 
1>C:\Program Files\boost\boost_1_38_0\boost/bind.hpp(1643) : warning C4180: qualifier applied to function type has no meaning; ignored 
1>  C:\Program Files\boost\boost_1_38_0\boost/bind.hpp(1677) : see reference to class template instantiation 'boost::_bi::add_cref<Pm,I>' being compiled 
1>  with 
1>  [ 
1>   Pm=void (__thiscall cGridAnimator::*)(int), 
1>   I=1 
1>  ] 
1>  .\mfm1.cpp(158) : see reference to class template instantiation 'boost::_bi::dm_result<Pm,A1>' being compiled 
1>  with 
1>  [ 
1>   Pm=void (__thiscall cGridAnimator::*)(int), 
1>   A1=cGridAnimator * 
1>  ] 
1>C:\Program Files\boost\boost_1_38_0\boost/mem_fn.hpp(318) : warning C4180: qualifier applied to function type has no meaning; ignored 
1>  C:\Program Files\boost\boost_1_38_0\boost/bind/bind_template.hpp(344) : see reference to class template instantiation 'boost::_mfi::dm<R,T>' being compiled 
1>  with 
1>  [ 
1>   R=void (int), 
1>   T=cGridAnimator 
1>  ] 
1>Project : error PRJ0002 : Error result 1 returned from 'C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\cl.exe'. 
+0

를 CL.EXE하지 않습니다 "? 내부 컴파일러 오류를보고합니까? –

+2

여기서 "컴파일러가 작동하지 않습니다"라는 메시지가 표시되지 않습니다. 심지어 컴파일러 오류가 표시되지 않습니다! C++ 컴파일러의 경고 2 개와'vcbuild'의 오류 만 있으면됩니다. 나는 당신이 1)/W4로 컴파일하고, 2) 당신의'.vcproj' 파일에 약간의 에러가 있다고 의심한다. 프로젝트 파일을 보여주십시오. 'cGridAnimator :: DoJob()'의 서명도 도움이 될 것입니다. –

+0

그 부분에 당신이 맞아. ICE는 대개 빌드 로그에 인쇄되고 응용 프로그램 충돌은 보통 errorlevel = 1 ... Dumb me가되지 않습니다. – gimpf

답변

3

변경 코드로 :

pThread[0] = new boost::thread(boost::bind(&cGridAnimator::DoJob, this, 0)); 

이 코드는 스레드 대신 void (int) 기능과 추가 인수에 void (void) 기능을 제공합니다.

+0

이것은 컴파일러의 충돌을 수정합니다. 나는 몇몇 시험을하고, 그것이 작동하는 경우에이 대답을 받아 들일 것이다. – ravenspoint

+0

좋은 캐치! 대답은 이렇게 명백 할 것이기 때문에 진술된다 : 당신은 어떻게 그것을 찾아 냈는가? – gimpf

+1

경고 메시지에서 DoJob의 서명을 볼 수 있습니다. 인수의 수가 맞지 않을 때마다 거의 동일한 컴파일러가 충돌합니다. – Willy

2

확실한 대답은 없습니다. 기본적으로 ICE는 항상 컴파일러 공급 업체에 연락하는 좋은 이유입니다.

실제 원인을 찾으려면 여전히 충돌을 나타내는 최소한의 프로그램을 찾으십시오. 이것은 가능하면 많은 코드를 제거하고 가능하면 많은 의존성을 제거하는 것을 의미합니다. 하나의 ICE에 대해 저는 한 번 새로운 프로젝트를 시작하고 문제를 의심했던 코드의 50 줄을 작성하는 것으로 성공했습니다 .

다음 해결 방법은 과거에 나에게 도움이 :

    • 특히 시간이 코드 생성이 흔들리는 약간 파일을 포함의
  1. 변경 순서를 것으로 보인다 링크 최적화 수준을 감소
    • 원본의 개정판을 알고있는 경우에만 합리적입니다. 그것은 당신이 다른 부스트 버전
      • 거기
    • 스위치 변경에 전념 할 수 있도록 발생하지하는 부스트 라이브러리 저자는 해결 방법을 활성화하거나 코드가 충분히 변경 될 수 있습니다, 작동을 중지 할 때 ICE는 더 이상 없습니다.
0

공지 사항 당신이 부스트 :: 바인드를 사용하고 매개 변수 유형이 잘못되면, Visual Studio를 사용하면 충돌 "무엇을 의미합니까 당신이 오류를 생각 나게하지만, PRJ0002에 대한 오류 및

관련 문제