|
CodeMaster 님이 쓰신 글 :
: 안녕하세요
:
: 기존에 개발되어 사용하던 32bit프로그램을 64bit으로 변환하는 과정에서 발견 된 현상있어 문의 드립니다.
:
:
: 현제 개발IDE는 Rad XE3 Update2를 사용하고 있습니다.
:
: 멀티스레드에서 로컬파일 DB접근이 동시에 이루어 질 수 있는 부분 있어
: Critical Section을 이용하여 동시접근을 제한하여 사용해 왔었습니다.
: 각 스레드에서 Critical Section 진입 및 해지(Enter, Leave)가 짝이 맞게 되어 있어
: 정상적으로 각 스레드에서 접근하여 읽기 쓰기 작업이 이루어 지며,
: windows 32bit환경으로 빌드하여 프로그램 사용시 정상동작을 확인했습니다.
:
:
: 하지만, 동일 프로그램을 windows 64bit환경으로 변경하고, 빌드하여 사용시 문제가 있었습니다.
: 한 쓰레드에서 CriticalSection 진입(EnterCriticalSection)후 나오더라도(LeaveCriticalSection)
: 다른 쓰레드에서 CriticalSection 진입시 Block되어 대기하고 있는 현상이 발생되고 있습니다.(Logging으로 문제점을 찾음)
:
: 테스트로 MS 비쥬얼스튜디오로 멀티스레드에서 CriticalSection사용하는 64bit 프로그램을 간단히
: 만들어 테스트 해보았지만, 해당 증상이 발견되고 있지는 않고 있습니다.
: 이러한 문제가 RadStudio의 C++ builder가 64bit으로 오면서 컴파일러가 LLVM Clang기반으로 추가된 것(바뀐 것?)으로 알고 있습니다.
: 이와 관련해서 생긴현상 인지도 모르겠다는 가설로, 일단 LLVM Clang에서 관련자료를 찾는 중입니다.
:
:
: 한 줄 요약
: -> '64bit에서는 LLVM Clang을 이용한 컴파일러로 인해 LeaveCriticalSection 명령이 않먹는거 같다'입니다.
:
: 혹시 관련 내용을 알고 계신분이 있으시다면 조언 부탁드립니다.
:
EnterCriticalSection, LeaveCriticalSection 등은 윈도우즈 API에 불과하고 vc든 빌더 bcc64든 테스트 해보면 정상적으로
문제 없이 실행 됩니다. api나 clang 컴파일러의 문제는 아니라는 거죠.
EnterCriticalSection API는 이미 다른 쓰레드에 의해서 Ownership이 결정된 상태라면 Blocking 되지만
같은 쓰레드에 의해서 호출될 때는 복수 호출되는것을 허용하고 있습니다. 그래야 데드락 현상을 피할 수 있으니까요.
같은 쓰레드에 의해서 복수 호출된 횟수 만큼 LeaveCriticalSection도 그 만큼 호출되어야 하고요. 내부적으로 카운트를
유지하고 있다는 거죠.
이런 식으로 같은 쓰레드에서 복수 호출되는 상황의 경우에는 EnterCriticalSection으로 진입해서 LeaveCriticalSection 로
나왔다 하더라도 내부 카운트가 0이 아니면 쓰레드 Owner는 Release된 상태가 아니라서 다른 쓰레드에 의해서 호출될 때
여전히 Blocking 상태가 될 수 있습니다.
추측컨데 컴파일러의 문제라기 보단 프로그램 로직에 어떤 문제가 있는게 아닐까 생각되는데요
프로그램 로직을 찬찬히 다시 살펴 보세요. 32비트와 64비트 각기 다른 환경에서 발생하는 차이로 인한
그게 포인터 일수도 있고 vcl 버그 등이 프로그램 로직과 물려서 어떤 문제를 내포하고 있을 가능성이 더 커 보이네요.
|