부스트를 잡고있는 동안 잠을 자면서 :: Intercrocess :: scoped_lock이 해제되지 않습니다.

StackOverflow https://stackoverflow.com/questions/977265

문제

나는 IPC를하고있다 리눅스 사용 boost::interprocess::shared_memory_object 에 따라 참조 (익명의 뮤텍스 예).

서버 프로세스가 있습니다 shared_memory_object 그리고 그것을 붙잡고있는 동안 그것에 글을 씁니다 interprocess_mutex a scoped_lock; 그리고 다른 사람이 작성한 모든 것을 인쇄하는 클라이언트 프로세스 -이 경우에는 int.

나는 문제를 해결했다 : 서버가 뮤텍스를 잡고있는 동안 서버가 잠을 자면, 클라이언트 프로세스는 결코 그것을 아키시킬 수 없으며 영원히 기다립니다.

버기 섬기는 사람 고리:

using namespace boost::interprocess;
int n = 0;
while (1) {
    std::cerr << "acquiring mutex... ";
    {
        // "data" is a struct on the shared mem. and contains a mutex and an int
        scoped_lock<interprocess_mutex> lock(data->mutex);
        data->a = n++;
        std::cerr << n << std::endl;
        sleep(1);
    } // if this bracket is placed before "sleep", everything works
}

섬기는 사람 산출:

acquiring mutex... 1
acquiring mutex... 2
acquiring mutex... 3
acquiring mutex... 4

고객 고리:

while(1) {
   std::cerr << "acquiring mutex... ";
   {
      scoped_lock<interprocess_mutex> lock(data->mutex);
      std::cerr << data->a << std::endl;
   }
   sleep(1);
}

고객 출력 (영원히 기다립니다) :

acquiring mutex...

문제는, 내가 괄호를 이전의 선으로 옮기면 sleep 전화, 모든 것이 작동합니다. 왜요? 나는 잠긴 뮤텍스로 자면서 뮤트가 영원히 잠겨 있다고 생각하지 않았다.

내가 가진 유일한 이론은 커널이 서버 프로세스를 깨울 때 범위가 끝나고 뮤텍스가 릴리스되지만 대기 프로세스는 실행할 기회가 주어지지 않는다는 것입니다. 그런 다음 서버는 잠금 장치를 다시 인용하지만 ... 많은 의미가없는 것 같습니다.

감사!

도움이 되었습니까?

해결책

당신의 이론은 정확합니다.

링크 된 참조에서 익명의 뮤 테스 예제의 맨 아래를 보면

우리가 볼 수 있듯이, 뮤텍스는 데이터를 보호하는 데 유용하지만 다른 프로세스에 이벤트에 알리지 않는 것이 유용합니다.

Mutex를 출시한다고해서 기다리고있는 다른 사람에게 알리지 않으며, 프로세스가 일어 났기 때문에 더 많은 일을하기 위해 일정이 많이 남아 있습니다. 그것은 다시 잠을 자기 전에 뮤텍스를 돌리고 다시 접근 할 것입니다. 이는 고객이 뮤트 자체를 획득 해야하는 첫 번째 기회입니다.

서버 이동 sleep() 범위를 벗어난 것은 뮤텍스가 자유롭고 클라이언트가 자체적으로 뮤텍스를 실행하고 얻을 수있는 기회를 제공한다는 것을 의미합니다.

전화 해보세요 sched_yield() (Linux 만 해당) 프로세서를 포기하고 싶지만 여전히 범위 내에서 잠을 자면. sleep(0) 작동 할 수도 있습니다.

다른 팁

뮤텍스를 들고있는 동안자는 것은 잘못된 것입니다. MUTEX는 일부 데이터 (IE 데이터-> A)를 보호하고 해당 데이터의 읽기/쓰기와 관련하여 범위를 최소화해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top