2013-07-18 2 views
0

공유 메모리에서 int deque를 공유하는 2 개의 프로세스 (생산자 및 고객)가 있습니다. 생산자 프로세스에서 양면 큐에 2 개의 숫자를 넣은 다음 해당 mutex를 잃어 버리는 대기 상태가됩니다. 자물쇠. 그런 다음 소비자 프로세스에서 숫자를 제거하고 인쇄합니다. 그런 다음 제작자가 기다리고있는 상태에 대한 알림을 보냅니다. 소비자는 두 번째 조건에서 기다립니다. 이 경우 생산자는 깨어나지 않습니다. 프로세스간에 동일한 뮤텍스를 사용하고 있습니다. 아래의 모든 코드를 찾으십시오.boost named_condition이 대기 프로세스를 깨우지 않고 있습니다.

#ifndef SharedMemory_h 
#define SharedMemory_h 

#include <boost/interprocess/managed_shared_memory.hpp> 
#include <boost/interprocess/containers/deque.hpp> 
#include <boost/interprocess/allocators/allocator.hpp> 
#include <boost/interprocess/sync/scoped_lock.hpp> 
#include <boost/interprocess/offset_ptr.hpp> 
#include <boost/interprocess/sync/named_condition.hpp> 

using namespace boost::interprocess; 

typedef allocator<offset_ptr<int>, managed_shared_memory::segment_manager> ShmemAllocator; 
typedef deque<offset_ptr<int>, ShmemAllocator> Deque; 

#endif 

프로듀서 과정 :

파일 shared_memory.h을 포함

#include "shared_memory.h" 

struct shm_remove 
{ 
    shm_remove() { shared_memory_object::remove("MySharedMemory"); } 
    ~shm_remove() { shared_memory_object::remove("MySharedMemory"); } 
} remover; 

struct mutex_remove 
{ 
    mutex_remove() { named_mutex::remove("MyMutex"); } 
    ~mutex_remove() { named_mutex::remove("MyMutex"); } 
} mutex_remover; 

//Create shared memory, mutex and condtion 
managed_shared_memory segment(create_only, "MySharedMemory", 10000000); 
named_mutex mutex(create_only,"MyMutex"); 
named_condition full(open_or_create,"FullCondition"); 
named_condition empty(open_or_create,"EmptyCondition"); 

const ShmemAllocator alloc_inst (segment.get_segment_manager()); 


int main() 
{ 
    Deque* MyDeque; 
    offset_ptr<int> a, b; 
    try{ 
     MyDeque = segment.construct<Deque>("MyDeque")(alloc_inst); 
     try{ 
      a = static_cast<int*> (segment.allocate(sizeof(int))); 
      b = static_cast<int*> (segment.allocate(sizeof(int))); 
     }catch(bad_alloc &ex){ 
      std::cout << "Could not allocate int" << std::endl; 
     } 
    }catch(bad_alloc &ex){ 
     std::cout << "Could not allocate queue" << std::endl; 
    } 
    scoped_lock<named_mutex> lock(mutex); 
    while(1) 
    { 
     while (MyDeque->size() == 2) 
     { 
      full.wait(lock); 
      std::cout << "unlocked producer" << std::endl; 
     } 

     if (MyDeque->size() == 0) 
     { 
      *a = 2; 
      MyDeque->push_back(a); 
     } 

     if (MyDeque->size() == 1) 
     { 
      *b = 4; 
      MyDeque->push_back(b); 
      empty.notify_one(); 
     } 
    } 
} 

소비자 과정 :

#include "shared_memory.h" 

managed_shared_memory segment(open_only, "MySharedMemory"); 
Deque* MyDeque = segment.find<Deque>("MyDeque").first; 

named_mutex mutex(open_only, "MyMutex"); 
named_condition full(open_only, "FullCondition"); 
named_condition empty(open_only, "EmptyCondition"); 

int main() 
{ 
    scoped_lock<named_mutex> lock(mutex); 
    while(1) 
    { 

     //volatile int size = MyDeque->size(); 
     while (MyDeque->size() == 0) 
     { 
      empty.wait(lock); 
     } 

     if (MyDeque->size() == 2) 
     { 
      std::cout << "Consumer: " << *MyDeque->front() << std::endl; 
      MyDeque->pop_front(); 
     } 

     if (MyDeque->size() == 1) 
     { 
      std::cout << "Consumer: " << *MyDeque->front() << std::endl; 
      MyDeque->pop_front(); 
      full.notify_one(); 
     } 
    } 
} 

일을 디버깅하는 동안이의 첫 번째 반복에 대한 확인을 이동하는 것 생산자는 양키에 숫자 2와 4를 놓고 전체 상태를 기다립니다. 그런 다음 소비자는 자물쇠를 가져와이 번호를 인쇄하고 전체 상태에 대해 notify_one을 수행 한 다음 잠시 기다립니다. 그 후에 프로듀서는 깨어나지 않습니다.

+0

나는 상호 향상 프로세스에 익숙하지 않지만, 공유 메모리의 '뮤텍스 (mutex)'가 두 프로세스 모두에서 작동한다고 생각할 이유가 있을까요? – Yakk

+1

Boost.Thread 라이브러리에도 다른 기능을 가진 유사한 객체가 존재하기 때문에 모든 동기화 객체가 Boost.Interprocess (즉, boost :: interprocess' 네임 스페이스)에 속해 있음을 명시 적으로 지정하십시오. –

+0

이름없는 뮤텍스를 사용할 때 사용할 수없는 경우 예외가 throw 될 때 함수가 있다고 생각합니다. 또한 내가 중단 점이있는 코드를 통해 디버깅 할 때 소비자가 뮤텍스를 얻으려고 시도하지만 프로듀서가 가질 수없는 경우가 있습니다. 생산자가 기다렸다가 뮤텍스를 잃을 때만 소비자가 그것을 얻는다. – rudasi

답변

0

mutex는 알림을 가로 질러 잠글 수 없습니다. 이것은 교착 상태의 원인입니다.

관련 문제