2014-01-22 3 views
0

아래와 같이 여러 if, else 조건 중 중요한 섹션을 넣을 수 있습니까? 이 같은임계 구역 및 다중 스레드 응용 프로그램에서 else, 조건

예 1

somefunction() 
    { 
      EnterCriticalSection(&(g_variable)); 

      if (...) 
      { 
       if (...) 
       { 
       ...  

       } 
       else 
       { 
        ... 
        if (...) 
        {...} 
       else if (...) 
        {...}  

      LeaveCriticalSection(&(g_variable)); 

       } 
      } 
      else 
      { 
        ...  
      } 


    } 

또는 둥지를 :

예를 도움에 미리 2 개

EnterCriticalSection(&g_List); 
EnterCriticalSection(&g_Variable); 
... 
LeaveCriticalSection(&g_List); 
LeaveCriticalSection(&g_Variable); 

감사합니다.

+1

예, 코드에 언급 된 중요 섹션을 넣을 수 있습니다. 예를 들어, 동일한 임계 섹션을 사용하는 경우 다른 스레드에 대해 동일한 코드 시퀀스를 유지해야합니다. 그렇지 않으면 교착 상태가 발생합니다. – Sumeet

+1

C++에서, 당신은 __always__를 건설시 중요한 섹션에 들어가는 클래스에 랩핑하고 파기해야합니다. 객체의 수명 기간 중에 여러 번 다시 나가거나 다시 입력해야한다면'Enter'와'Leave' 함수를 추가하십시오. –

답변

1

일 수 있으며, 이되어야합니다.

귀하의 질문에 표시되는 내용을 수행하십시오. 적어도 내 의견으로는 이되어야합니다 (C++을 사용하고 있기 때문에). LeaveCriticalSection 호출을 EnterCriticalSection 호출과 일치하도록 자동화하기 위해 RAII 래퍼를 사용합니다.이러한 사용

class crit_sect { 
    CRITICAL_SECTION cs; 

    void lock() { EnterCriticalSection(&cs); } 
    void unlock() { LeaveCriticalSection(&cs); } 
    friend class lock; 

    crit_sect(crit_sect const &); /* = delete; */ 
    crit_sect &operator=(crit_sect const &other); /* = delete; */ 
public: 
    crit_sect() { InitializeCriticalSection(&cs); } 
    ~crit_sect() { DeleteCriticalSection(&cs); } 
}; 

class lock { 
    crit_sect &cs; 
public: 
    lock(crit_sect &c) : cs(c) { cs.lock(); } 
    ~lock() { cs.unlock(); } 
}; 

, 당신은 같은 거라고 :

if (whatever) { 
    lock list_lock(g_List); 
    lock var_lock(g_Variable); 

// ... 

} 

을 ... 그리고 실행이 두 개의 잠금이 정의 된 범위를 벗어나면, 소멸자가 자동으로 중요한 잠금 해제, 실행합니다 섹션. 이것은 편리하고 편리합니다. 예외를 사용하는 경우에는 정상 실행 대신 예외를 통해 범위를 종료하면 중요 섹션이 계속 잠금 해제된다는 의미이기 때문에 더욱 중요 해집니다.

+0

위의 예제 2에서 솔루션을 사용하는 경우 교착 상태가 발생하지 않을까요? – maciekm

+1

@maciekm : 코드에 교착 상태가 발생하지 않습니다. 당신이하는 일에 따라 교착 상태가 발생할 수 있습니다. 교착 상태는 대부분 두 개 이상의 잠금을 동시에 획득하려고 할 때 발생합니다. 이 경우 모든 것을 동일한 순서로 획득하려고합니다. 'lock locker1 (a); locker2 (b)를 잠급니다; 모든 곳에서 작동합니다. 'lock locker1 (b);를 추가하십시오. locker2 (a);를 한 곳에서 사용하면 잠재적 인 교착 상태가 발생할 수 있습니다. –

2

예 1에서 이것은 나쁜 습관입니다. 코드 블록

EnterCriticalSection(&g_Variable); 
{ 
    .... 
} 
LeaveCriticalSection(&g_Variable); 

더 나은 아니라 더 나은 위협 중요한 부분은, 범위 CS 클래스를 사용하는 것입니다

class CScopeCS{ 
    CRITICAL_SECTION& m_cs; 
public: 
    CScopeCS(CRITICAL_SECTION& cs):m_cs(cs){ 
    EnterCriticalSection(cs); 
    } 
    ~CScopeCS(){ 
    LeaveCriticalSection(m_cs); 
    } 
} 

및 중요 섹션 블록 종료, 그것은 소멸자를 자동으로 호출 할 때.

예 2에서
{ 
    CScopeCS scopeLock(g_cs); 
    .... 
}//end of critical section 

, 당신이 그것을 쓴처럼 작동하지만 당신은 더 나은 먼저 마지막 떠나 :

EnterCriticalSection(&g_List); 
EnterCriticalSection(&g_Variable); 
... 
LeaveCriticalSection(&g_Variable); 
LeaveCriticalSection(&g_List); 

을하지만 당신은 당신의 코드에서 같은 순서로 두 가지 중요한 부분을 취해야합니다 교착 상태를 방지합니다. (예 : 첫 번째 g_List, g_Variable) g_Variable을 이미 입력하고 g_list에도 입력하려면 g_Variable을 그대로두고 순서대로 가져와야합니다.

1

짧은 답변 : 가능합니다. 하지만 Enter/LeaveCriticalSection 쌍으로 실수를 저지르는 것은 쉽습니다. 자신의 코드에 따르면 위쪽의 임계 구역을 가져온 후 임계 구역이 LeaveCriticalSection으로 해제되지 않은 코드 경로가 있습니다. 경로 중 하나는 첫 번째 if 문에서 else 블록을 가져 오는 부분이지만 다른 코드는 그 사이에있는 일부 코드가 예외를 throw하는 경로입니다.

당신은 C++로 질문 태그를 지정했습니다. C++ 11이 사용 가능하다면 훌륭한 대안이 있습니다 : recursive_mutex와 lock_guard와 같은 표준 헤더의 클래스입니다. 귀하의 코드는 다음과 같습니다 :

recursive_mutex g_variable; 

someFunction() 
{ 
    lock_guard<recursive_mutex> lock(g_variable); 

    if (...) 
     ... 
    else 
     ... 
} 

이제는 someFunction()을 떠날 때 뮤텍스가 해제된다는 보장이 있습니다. 그리고 적은 수를 입력해야하며 코드도 이식성이 있습니다.

관련 문제