2011-09-26 2 views
7

여러 스레드에서 만들 수있는 클래스가 있습니다. 하지만 하나의 함수에서 코드를 보호해야하므로 boost 프로세스 간 뮤텍스를 사용하기로 결정했습니다. 모든 클래스는 만들거나 그것의 생성자에서 같은 뮤텍스를 엽니 다named_mutex를 부스트하고 remove() 명령을 사용합니다.

MyClass::MyClass() 
{ 
     boost::interprocess::named_mutex m_Lock(
       boost::interprocess::open_or_create, "myLock"); 
} 

그래서 지금 중요한 코드 부분이 호출되는 시점이 온다 : (

int MyClass::MyFunction() 
{ 
     boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(
        m_Lock, boost::interprocess::try_to_lock); 
     if(!lock) 
     { 
      return -1; 
     } 
     // else do some stuff here 
} 

함수 후 정리하려면를하고 싶은 그 사실 모든 코드가 잘 작동

MyClass::~MyClass() 
{ 
     boost::interprocess::named_mutex::remove("myLock"); 
} 

하지만 내가 가진 하나의 문제가있다 :

0 내 클래스 소멸자에서 삭제 명령을 사용하여) 부스트 페이지에 설명

시스템에서 명명 된 뮤텍스를 삭제합니다 : 그것이 제거 명령의 설명에서 말했다됨에 따라

. 오류가 발생하면 false를 반환합니다. 절대 던지지 마. 다른 스레드가 그냥 잠긴 경우에도 (이미이 사건을 시도 - - 그것은 더 이상 다음 잠겨 있지)

은 그래서 remove 명령은 단지 시스템에서 뮤텍스가 삭제 의미한다. 그래서 내 문제는 다음입니다 : 내가 가진 예를 들어 3 스레드 (A, B 및 C) - 이제 다음과 같은 일이 발생 :

  1. 프로세스 A는 클래스의 인스턴스를 생성하는 함수를 호출하고
  2. 그것을 고정
  3. 프로세스 B는, 클래스의 인스턴스를 생성하는 함수를 호출하지만 코드에 액세스 할 수 없습니다 (대기합니다 예)
  4. 프로세스 A는 보호 된 코드를 완료하고이 보호 된 코드
  5. 프로세스 B 이득 액세스의 잠금이 해제됩니다 그것을 잠급니다.
  6. 가공 ■ 클래스의 인스턴스를 삭제합니다. -> remove 명령이 호출됩니다.
  7. 프로세스 C가 클래스의 인스턴스를 만들고 함수를 호출하며 제거 명령이 뮤텍스 -> 오류를 지웠으므로 코드에 액세스 할 수 있습니다.

그럼 이제 누군가가 "그럼 전화를 걸지 마!"라고 말할 수 있습니다. 나는 named_mutex가 시스템에 쓴 이후로 프로그램이 종료 되더라도 명시 적 호출없이 지워지는 것을 의심한다. 누구나 도움이 필요합니까?

+0

귀하의 질문과 "스레드"및 "프로세스"의 상호 사용에 혼란 스럽습니다. 어느 상대인가? 스레드? 또는 프로세스? 일반적으로 명명 된 mutis는 단일 프로세스 내에서만 멀티 스레드 된 경우 매우 큰 유용성을 갖습니다. –

+0

죄송합니다. 나는 글씨를 쓰는 동안 조금 혼란 스러웠습니다. 사실 나는 다른 프로세스를 가지고있다. 앞에서 말했듯이 스레드 만 있으면 이름 지정된 뮤텍스를 실제로 사용할 필요가 없습니다. – Toby

답변

6

boost docs에서 remove으로 전화 할 필요가 없습니다. named_mutex의 소멸자는 프로세스에 리소스가 더 이상 필요하지 않음을 OS에 자동으로 알려줍니다. 당신은 아마도 정리를위한 소멸자의 내장 된 동작에 의존하는 것이 좋습니다.

명시 적으로 remove를 호출하면 명명 된 뮤텍스를 사용하려고 시도하는 다른 프로세스 나 스레드가 뮤텍스의 모든 연산에서 실패하게됩니다. 사용법이 조정되는 방식에 따라 다른 프로세스에서 발생하는 데이터 경합 또는 충돌/예외가 발생할 수 있습니다.

~ named_mutex();

Destroys * this는 호출 프로세스가 리소스를 사용하여 완료되었음을 나타냅니다. 소멸자 함수는이 리소스에 대해이 프로세스에서 사용하기 위해 시스템에서 할당 한 모든 시스템 리소스를 할당 해제합니다. 열린 생성자 오버로드를 호출하여 리소스를 다시 열 수 있습니다. 시스템에서 자원을 지우려면 remove()를 사용하십시오.

+0

그래서 권리를 얻으면 remove()를 호출하지 않는 한 리소스가 시스템에 남을 것입니다 (소멸자가 호출 되더라도).하지만 소멸자가 OS에 리소스가 " 잠금 해제 "되어 다른 프로세스가 잠금을 설정할 수 있습니까? 그게 그렇게 맞습니까? – Toby

+0

나는 그 (것)들, 나 자신과 다량 놀지 않으며, 그러나 뮤텍스를 사용하는 프로세스의 수가 0이 될 경우, 자원은 풀릴 것이라는 점을 나는 생각한다. sem_close()는 sem이 가리키는 이름의 세마포어를 닫음으로써,이 세마포어를 해제하기 위해 시스템이 호출 한 프로세스에 할당 한 자원을 허용한다. . –

+10

어쨌든 나는 어제 재판과 시행 착오를 조금 했어. 뮤텍스의 리소스는 공유 메모리 (/ dev/shm /)에 있습니다. 생성 된 후에는 remove()를 호출하거나 시스템을 재부팅 할 때까지 거기에 머물러있게됩니다. 공유 메모리를 지우려면 (예 : 혼자서 지우기) 다른 작업을 수행하십시오. 객체 자체에는 잠긴 상태인지 여부에 대한 정보가 들어 있습니다. 뮤텍스가 파괴되면 잠금 해제되지만 지워지지는 않습니다! 따라서 유일한 문제는 프로그램이 충돌하고 소멸자를 호출 할 수없고 개체가 잠긴 상태로 유지 될 수 있다는 것입니다. – Toby

0

아마도 뮤텍스의 공유 사용 카운터가 필요합니다. 소멸자에서 뮤텍스를 잠그고, 감소시키고, 감소 후에 0이면 여전히 잠긴 뮤텍스를 할당 해제합니다. 당신은 그것으로 현재의 경쟁 조건을 막을 것입니다.