2013-01-09 23 views
1

시작될 때 스레드를 만드는 프로그램이 있습니다 (스레드 생성을 위해 C++ Boost 라이브러리를 사용하고 있습니다). 주 프로그램에서 내 정리 기능을 등록했습니다. 당신은 내가 스레드를 중단하고 스레드가 정리 물건을 않도록 다음 (기본 과정) 여기서 기다려 깨끗한 종료 과정에서 위에서 볼 수 있듯이프로그램 종료 후 C++ const static의 동작

atexit(cleanExit) 
// Trap some signals for a clean exit. 
signal(SIGQUIT, signalled) 
signal(SIGABRT, signalled) 
signal(SIGTERM, signalled) 
signal(SIGINT, signalled) 

static void signalled(int signal) 
{ 
    exit(signal) 
} 
static void cleanExit(void) 
{ 
    thread->interrupt(); 
    thread->join(); 
} 

. 스레드 -> 인터럽트를 호출하면 스레드가 중단되고 스레드 정리를 수행합니다. 여기까지 모든 것이 원활하게 진행되고 아무 문제가 없습니다.

하지만 스레드에서 정리 기능을 호출 할 때 문제가 발생합니다. 정리 함수에서 서버에 상태를 다시 보내고 있습니다. 유틸리티 함수를 만들었습니다.이 유틸리티 함수에서 클래스의 "const static string"멤버에 액세스하고 있습니다. 문제는 내 const 정적 문자열에 액세스 할 때 응용 프로그램이 막혔다는 것입니다. strace로 확인한 결과 Seg 오류가 발생했습니다. 그러나이 "const static string"을 "const string"으로 변경하면 정리가 원활 해집니다.

QUESTION 일단 프로그램이 종료되면 C++ "const static"의 동작은 어떻습니까? 출구가 호출 될 때 (위의 경우에서 볼 수 있음) 또는이 동작에 대한 생각을 포기합니까?


업데이트 # 1 여기

스레드 핸들러 함수이다. 위에서 언급 한 것처럼 Boost 스레드. 주요 프로그램은 스레드 -> 인터럽트 호출하면

try { 
    while (true) { 
     // Do your job here. 
     // 1: We can be interrupted. 
     boost::this_thread::interruption_point(); 
    } 
} 
catch (boost::thread_interrupted const&) 
{ 
    // Before exiting we need to process all request messages in the queue 
    completeAllWorkBeforeExiting(); 
} 

, 스레드 # 1에서 thread_interrupted 예외를 일으킬 것이며, 내 정리 물건을하고이 예외를 잡기.

답변

2

const 개체가 파괴되면 영향을주지 않습니다.

static 개체는 생성 순서와 반대 순서로 파괴됩니다. atexit은 소멸자로 주어진 함수로 익명의 static 객체를 만듭니다. 즉, static 객체 소멸자와 atexit 콜백이 건설/등록 반대 순서로 발생합니다.

exit을 신호 처리기에서 호출하는 것은 완전히 안전하지 않습니다. 모든 시그널 핸들러는 실제로 쓰레드에 의해 나중에 폴링되는 플래그를 설정하도록 허용된다. 앞에서 언급했듯이 신호 처리기는 인터럽트 시간에 실행되므로 시스템 호출이 중단 될 수 있습니다. 그것은 mallocmalloc의 다중 스레드 잠금을 우회하는 방식으로 인터럽트 할 수 있습니다. 이는 재진입 성이 동일한 스레드에서 일어나기 때문에 일반적으로 발생하는 것과 다릅니다.

그래서 모든 종류의 예측할 수없는 행동의 원인입니다. 더 이상 보지 않고서는 static의 효과에 대해 더 자세히 설명 할 수는 없지만 개체의 수명을 변경하거나 개체별로 인스턴스화하는 것과 관련이있을 수 있습니다.

+0

감사합니다. 실제 질문에 대한 업데이트를 제공했습니다. 이것을 고려해 볼 때 왜 신호 처리기에서 나가는 것이 안전하지 않은지 자세히 설명해주십시오. –

+0

Potatoswatter - Re *'static objects'는'atexit' 핸들러가 생성 된 순서와 반대 순서로 파괴됩니다. * -'atexit' 핸들러가'main'에 들어간 후에 등록 된 경우에만 해당됩니다. 정적 객체의 생성자의 동적 범위 내에서'atexit'로 등록 된 함수에 대해서는 좀 더 복잡해집니다. –

+0

@FarrukhArshad - 신호 처리기의 동적 범위 내에서 'exit'을 호출하면 정의되지 않은 동작이 발생합니다. C99에 따르면, 시그널 핸들러의 동적 범위 내에서 호출 될 수있는 유일한 라이브러리 함수는'_Exit'와'abort'입니다. –

관련 문제