2014-09-26 4 views
1

내가 스택 중 하나가 출구 동시에 덤프에 종료 후 다른 스레드의 전역 변수에 액세스하는 것이 안전합니까?

#0 0x00007fe2beac80a4 in __lll_lock_wait() from /lib64/libpthread.so.0 
#1 0x00007fe2beac3444 in _L_lock_1087() from /lib64/libpthread.so.0 
#2 0x00007fe2beac32b6 in pthread_mutex_lock() from /lib64/libpthread.so.0 
#3 0x00007fe2bece5325 in _dl_fini() from /lib64/ld-linux-x86-64.so.2 
#4 0x00007fe2bd73a5e5 in __run_exit_handlers() from /lib64/libc.so.6 
#5 0x00007fe2bd73a635 in exit() from /lib64/libc.so.6 

을 호출되었는지 보여줍니다 덤프를 분석하고하는 것은 글로벌 변수에 액세스하려고 다른 스레드입니다. 따라서 exit가 호출 된 후에 다른 스레드의 전역 변수에 액세스하는 것이 안전합니까? 전역 변수가 종료 된 후 "언제든지"삭제 될까요?

+0

여전히 여러 스레드가 실행되는 동안 [exit()]] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/exit.html)을 호출하는 것은 좋지 않습니다. 'exit()'에 대한 POSIX 사양은 ['_exit()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html)을 참조하고 프로세스의 결과 중 하나는' _exit'는 쓰레드가 클린업 핸들러 등을 호출하지 않고 종료된다는 것입니다. (_ _Exit() 또는 _exit() 호출로 종료 된 _Threads는 취소 정리 핸들러 또는 쓰레드 데이터 소멸자를 호출하지 않습니다 ._) –

+1

나는 여러 스레드가 활성화되어있는 동안 프로세스를 종료하는 것에 대한 직접적인 조언을 찾지 못했지만 전역 변수 등으로 어지럽 혀지는 동안 다른 프로세스가 전체 프로세스를 죽이는 동안, 깨지기 쉽고, 불확실하고, 일반적으로 나쁜 아이디어가 될 수밖에 없다. –

+0

글쎄,별로 중요한 것은 아닌 멀티 태스킹 OS. Windows, Linux 등은 메모리의 할당을 해제하기 전에 프로세스의 모든 스레드를 중지합니다. 복잡한 응용 프로그램에서 바쁜 프로세스의 스레드를 제외한 모든 스레드를 중지하는 것은 매우 어려울 수 있습니다. 이는 실행되는 동안 앱의 성능에 아무런 추가도하지 않는 개발, 작성, 테스트 등을 필요로하는 더 많은 코드 (즉, 더 많은 버그)를 의미합니다.OS는 사용자 코드보다 스레드를 멈추게하는 것이 훨씬 낫습니다. 왜냐하면 더 나은 도구가 있고 언제든지 모든 코어에서 실행되는 스레드를 멈출 수 있기 때문입니다. 사용자 코드에 문제가있는 것입니다. –

답변

1

그래서 출구 이 호출 된 후 다른 스레드에서 전역 변수에 액세스하는 것이 안전합니까?

중요한 모든 OS에서 그렇습니다. exit가 호출 된 후 다른 스레드의 로컬/자동 저장 영역에 액세스하는 것이 안전합니다. Windows/Linux 등 디자이너들은 디자인 타임에이 문제를 생각해 냈고 프로세스 종료 시퀀스를 개발하여 메모리가 해제되기 전에 프로세스의 모든 스레드가 중지되도록했습니다. 실행 중 상태가 아닌 프로세스 스레드는 다시 실행될 수 없도록 상태가 변경됩니다. 'exit'를 호출 한 스레드와 다른 코어에서 실행중인 프로세스 스레드는 실행중인 코어에 대한 하드웨어 인터럽트를 통해 해당 실행을 강제로 제거합니다. 모든 쓰레드가 멈출 때만 다른 프로세스에 의해 재사용을 위해 해제되고 해제 된 메모리와 같은 자원이있다.

종료 된 후에 전역 변수가 "언제든지"삭제됩니까?

예. 전역을 호스팅하는 메모리 세그먼트는 종료가 호출 된 후 얼마 후에 OS에 의해 해제됩니다. 그러나 아무 때나 프로세스 스레드가 그 시점에 실행될 것이기 때문에 이것은 중요하지 않습니다.

모든 exit() 호출이 동일하게 만들어집니다. 일부는 정적 dtors 등을 실행하기 전에 OS를 호출하여 프로세스를 종료하고 이로 인해 실제로 실행중인 스레드를 호출하여 문제가 발생할 수 있으므로 UB가 발생할 수 있습니다./segfaults. 이것은 사소한 dtors가 아닌 POD가 아닌 클래스에서 더 많이 발생합니다.

이것이 실제 문제인 것으로 판명 된 경우 정적 담당자를 실행하지 않는 종료 호출을 사용하거나 (dtor이 수행하거나 수행해야하는 작업에 따라 중요 할 수도 있음) 또는 어쨌든 나쁜 계획이 아닌 정적 전역을 사용하지 않음으로써 문제를 피하거나 최후의 수단으로 사용자 공간에서 문제가되는 스레드를 공동으로 종료하려고 시도하는 비참하고 보통 피할 수있는 운동을 통해 exit()으로 전화하십시오.

+0

하지만 전역 변수 소멸자 중 하나가 호출되었습니다. 가능한가요? OS : SUSE10 – Nasir

+0

@Nasir 예, 예, 편집합니다 :) –

관련 문제