2009-08-26 5 views
9

클래스 별 new_handler 구현의 경우 책 "effective C++"에서 다음 예제를 발견했습니다. 이 문제는 멀티 스레드 환경에서 보입니다. 내 질문은 멀티 스레딩 환경에서 클래스 별 new_handler를 얻는 방법입니까?특정 클래스 사용 set_new_handler

void * X::operator new(size_t size) 
{ 
    new_handler globalHandler =    // install X's 
    std::set_new_handler(currentHandler); // handler 
    void *memory; 
    try {          // attempt 
     memory = ::operator new(size);   // allocation 
    } 
    catch (std::bad_alloc&) {     // restore 
     std::set_new_handler(globalHandler);  // handler; 
     throw;         // propagate 
    }           // exception 
    std::set_new_handler(globalHandler);  // restore 
               // handler 
    return memory; 
} 

답변

4

네가 맞아. 아마도 스레드로부터 안전하지 않을 수 있습니다. 대신 nothrow version of new를 사용하여 같은 다른 방법을 고려하는 것이 좋습니다 :

void* X::operator new(std::size_t sz) { 
    void *p; 
    while ((p = ::operator new(sz, std::nothrow) == NULL) { 
    X::new_handler(); 
    } 
    return p; 
} 

이 메모리 할당이 실패 할 때마다 클래스 고유의 핸들러를 호출하게됩니다. operator new 오버로드를 둘러싼 모든 골칫거리를 정말로 이해할 때까지는 이것을하지 않을 것입니다. 특히 허브 셔터 (Herb Sutter)의 두 부분으로 된 기사 을 던지려 할 새 메시지, Part 1Part 2을 읽어보십시오. 재미있게 충분히, 그는 nothrow 버전을 피하기 위해 말한다. .. hmmm.

0

C++은 스레드가 무엇인지 (아직) 알지 못합니다. 당신은 컴파일러/C++ 표준 라이브러리/운영체제/쓰레드 라이브러리 매뉴얼을 참조하여 이것을 할 수있는 쓰레드 안전한 방법을 결정하거나 심지어 가능할지를 결정해야 할 것이다. 새 처리기가 응용 프로그램에서 동일해야한다고 제안합니다. 이것은 매우 유연한 메커니즘이 아니며 할당 자나 아마도 공장 (factory)을 사용하는 것이 더 나을 것입니다. 사용자 지정 새 처리기에서 수행하려는 작업은 무엇입니까?

0

아마 당신은 틀린 길을보고 있습니다. (메모리 할당 대부분이 코드 외부에있을 수 있기 때문에) 전체 애플리케이션이 메모리를 할당하는 것을 제한 할 수있는 방법이 없다고 생각합니다. 그렇게하는 가장 좋은 방법은 할 수있는 것을 제어하는 ​​것입니다. 즉 구현 핸들러의

처리기가 프로그램의 시작 부분에서 "OutOfMemoryHandler"클래스의 인스턴스를 호출하고 (기본 호출을 호출하여) 기존 처리기를 호출하도록 설정합니다. 클래스 특정 처리를 추가하려면 동적 동작에 대해 선호하는 C++ 기술을 사용하여 OutOfMemoryHandler에 비헤이비어를 추가합니다.

이 솔루션은 단일 스레드 환경에서는 잘 작동하지만 다중 스레드 환경에서는 실패합니다. 멀티 스레드 환경에서 작동하게하려면 호출자가 핸들러 객체에 특정 스레드에서 작업하고 있음을 알릴 필요가 있습니다. thread-id를 클래스와 함께 전달하는 것이 좋은 방법입니다. 핸들러가 호출되면 스레드 ID를 확인하고 연관된 클래스를 기반으로 실행할 동작을 결정합니다. new() 호출이 끝나면 단순히 thread-id의 등록을 취소하여 올바른 기본 동작을 보장합니다 (이미 기본 처리기를 재설정하는 것처럼).