2014-08-28 3 views
0

내 코드가 종료되지 않는 이유를 모르겠습니다. 내가 여기에 놓친 것은 분명히 분명한 것입니다. 도와주세요!C++ 스레드 프로그램이 종료되지 않습니다

using namespace std; 
int main(int argc, char* argv[]) 
{ 
    MyClass *m = new MyClass(); 
    thread t1(th,m); 

    delete m; 
    m=NULL; 
    t1.join(); 
    return 0; 
} 

void th(MyClass *&p) 
{ 
    while(p!=NULL) 
    { 
     cout << "tick" << endl; 
     this_thread::sleep_for(chrono::seconds(1)); 
    } 
    return; 
} 
+1

'while (p! = NULL)'루프 내부에 절대 쓰여지지 않아서이 루프를 무한 루프로 바꿀 수 있기 때문에 'p'가 변경되지 않는다고 가정하면 컴파일러 최적화로 인한 것일 수 있습니다. 'volatile' 스토리지 클래스 지정자를 파라미터'p'에 추가 해보십시오 : 이것은 컴파일러에게 변수가 포함하는 것에 대해 아무 것도 생각할 수 없다는 것을 알려주기 때문에 매번 메모리에서 다시 읽습니다 (최소한 C++ 03 ; 나는 C++ 11에서 의미가 바뀌 었다고 생각하지만). –

+4

@j_random_hacker : 아니요, '휘발성'을 사용하지 마십시오 : 여러 스레드에서 액세스 할 때 필요한 동기화 또는 원 자성을 제공하지 않습니다 (기본 하드웨어에서 이러한 속성을 제공하는 일부 플랫폼에서는 우연히 "작동"할 수 있지만 isn 휴대용 솔루션). 'std :: atomic' 또는 뮤텍스 (mutex)로 보호해야합니다. –

+1

또한 공유 변수를 폴링하는 대신 스레드 통신을위한 조건 변수를 살펴보십시오. – stefaanv

답변

10

스레드에 m 사본이 제공되고 참조가 아닙니다. 참조 래퍼를 사용하면에게 참조 제공합니다 :

thread t1(th,std::ref(m)); 

이 프로그램은 아마 종료 후 예상되므로을; 하지만 하나의 스레드에서 m을 수정하고 동기화하지 않고 다른 스레드에서이를 읽는 데이터 경주로 인해 정의되지 않은 동작이 계속 발생합니다. 이 문제를 해결하려면 std::atomic<MyClass*>을 사용하거나 뮤텍스로 두 액세스를 모두 보호하십시오.

+0

그게 처음에 생각한 것입니다. 그러나 인수는 실제로 * MyClass에 대한 포인터에 대한 참조이므로 주 스레드의 'm'에 대한 할당은 새 스레드에서'p '를 통해 볼 수 있어야합니다. –

+2

@j_random_hacker : 아니요,'m'의 복사본이'thread' 생성자에 전달되고 스레드는 그 복사본에 대한 참조를받습니다. 'm' 자체에 대한 참조를 얻으려면'std :: ref'가 필요합니다. –

+0

나는 감사합니다. 나는 C++ 11에서 "완벽한 포워딩"덕분에 이런 종류의 문제가 더 이상 문제가 아니었다 고 생각했다.'스레드 '도구가 자동으로 여기에 "옳은 일을 할 수 없다"라는 이유가 있을까요? –

관련 문제