2012-03-21 2 views
1

DLL에 명시 적으로 링크를 수행하는 코드를 작성 중입니다. 이 코드는 .lib 파일로 암시 적으로 연결하는 대신 내 사용자에게 제공됩니다. 순간 내 계획 코드는 다음과 같습니다이 코드에 동기화를 추가해야합니까?

void DisableModule(int Module) 
{ 
    typedef void (*DisableModuleProc)(int); 
    static DisableModuleProc proc = NULL; 
    if (proc == NULL) 
     proc = (DisableModuleProc)GetProcAddress(hModule, "DisableModule"); 
    proc(Module); 
} 

이 양식의 많은 기능이있다, 나는이 질문의 목적을 위해 검사 오류를 절제했다.

내 스레드 보안 문제가 있습니다. 이 함수는 여러 스레드에서 동시에 호출 될 수 있습니다. 분명히 정적 변수 _DisableModule에 경주가 있습니다. 내 생각에 _DisableModule은 기계 단어 경계 (대상에 따라 32 비트 또는 64 비트 경계)에 정렬되므로 절도가 발생할 수 없으므로 인종은 양성입니다. GetProcAddress이 필요한 것보다 더 많이 호출 될 수도 있지만 프로그램의 정확성에 영향을 미치지는 않습니다.

내 분석이 맞습니까?

+0

호출 된 함수 (_DisableModule) 자체가 스레드 안전합니까? 또한 밑줄과 대문자로 시작하는 식별자는 예약되어 있습니다. – zvrba

+0

@zvrba 예, 가져온 함수는 스레드 세이프입니다. 예약 된 식별자에 대한 조언을 많이 주셔서 감사합니다. 나는 C에 능통하지 않다. –

+0

프로세서 유형에 따라 다르지만 x86 또는 x64에서는 정상적으로 작동합니다. ARM에 대해서는 확실하지 않지만 메모리 모델이 약합니다. 스레드를 사용할 때 항상 '미안한 것보다 안전합니다'를 호출하는 것이 현명합니다. –

답변

2

이 코드는 x86 및 AMD64에서 완벽하게 안전합니다. 최악의 경우 GetProcAddress이 여러 번 호출됩니다.

다른 아키텍처에서는 부분 쓰기가 중단되는 데 문제가있을 수 있습니다. 이것을 우회하기 위해, 당신은 원자 (InterlockedComparExchange ...)를 사용할 수 있지만, 여기서는 불필요합니다.

+0

그렇다면 일부 아키텍처에서는 기계어 크기의 정렬 된 쓰기가 읽기와 관련하여 원자 적이지 않다는 것을 말하는 것입니까? –

+1

Aehm, 포인터가 워드 크기가 아닌 ... (예 : 16 비트 아치, 32 비트 (멀리) 포인터) 또는 정렬되지 않은 주소의 쓰기가 허용되는 아키텍처가 있지만 캐시 라인 경계에서 원자적일 수는 없습니다 ... . 그러나 당신은 그들 위에서 창을 달리게 할 수 없다. .... – Christopher

0

간단한 잠금 장치로 처리해야합니다.
잠시 후에 proc==NULL 인 경우에만 잠금 장치를 사용해야하므로 잠시 후에는 잠금이 해제됩니다. 그래서 논쟁은 문제가되지 않습니다.
자물쇠를 보관하거나 보관하지 않고 GetProcAddress으로 전화 할 수 있습니다.

옵션 1 :

if (proc == NULL) { 
    lock(); 
    proc = (DisableModuleProc)GetProcAddress(hModule, "DisableModule"); 
    unlock(); 
} 

옵션 2 :

if (proc == NULL) { 
    DisableModuleProc tmp = (DisableModuleProc)GetProcAddress(hModule, "DisableModule"); 
    lock(); 
    if (proc == NULL) { 
     proc = tmp; 
    } else { 
     // Any free needed? 
    } 
    unlock(); 
} 
+0

고마워요.하지만 자물쇠가 필요 없도록 노력하고 있습니다. –

+0

'GetProcAddress'가 쓰레드에 안전하고 항상 똑같이 반환한다면, 당신은 정말로 괜찮습니다. 그러나 자물쇠는 제가 제안한 방법과 거의 아무런 관련이 없습니다. – ugoren

+0

스레드 안전합니다. 그러나 그렇지 않은 경우 옵션 2가 실패합니다. –

관련 문제