공유 메모리 개체 생성을 위해 C ++ 클래스 템플릿에 할당자를 추가

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

  •  19-09-2019
  •  | 
  •  

문제

요컨대, 내 질문은 다음과 같습니다. 수업이 있다면 MyClass<T>, 당신이 가진 사례를 지원하기 위해 클래스 정의를 어떻게 변경할 수 있습니까? MyClass<T, Alloc>, STL 벡터가 제공하는 방식과 유사합니다.

공유 메모리에 대한 할당자를 지원하려면이 기능이 필요합니다. 구체적으로, 공유 메모리에서 링 버퍼를 구현하려고합니다. 현재 다음과 같은 CTOR가 있습니다.

template<typename ItemType>
SharedMemoryBuffer<ItemType>::SharedMemoryBuffer( unsigned long capacity, std::string name )

어디 ItemType 버퍼의 각 슬롯에 배치 할 데이터의 유형입니다.

이제 메인 프로그램에서 버퍼를 만들 때 이것은 화려하게 작동합니다.

SharedMemoryBuffer<int>* sb;
sb = new SharedMemoryBuffer<int>(BUFFER_CAPACITY + 1, sharedMemoryName);

그러나이 경우 버퍼 자체는 공유 메모리에서 생성되지 않으므로 다른 프로세스에 액세스 할 수 없습니다. 내가하고 싶은 것은

typedef allocator<int, managed_shared_memory::segment_manager>  ShmemAllocator;
typedef SharedMemoryBuffer<int, ShmemAllocator> MyBuffer;

managed_shared_memory segment(create_only, "MySharedMemory", 65536);
const ShmemAllocator alloc_inst (segment.get_segment_manager());
MyBuffer *mybuf = segment.construct<MyBuffer>("MyBuffer")(alloc_inst);

그러나 클래스 템플릿에 명시 적 할당자를 추가하는 방법을 모르겠습니다.

도움이 되었습니까?

해결책

내가 혼란스럽게 만드는 것은, Shm (SharedMemory)에 객체를 할당하거나 만들어야하는 이유는 예를 들어 크기 65536 바이트의 공유 메모리를 예약 한 다음 주소에서 공유 메모리를 얻는다고 가정 해 봅시다. 0x1ABC0000, 예약 성공이 있으면 무료로 직접 액세스 할 수있는 메모리 공간이 있습니다. 0x1ABC0000 to 0x1ABCFFFF.

그런 다음 애플리케이션이 크기의 SHM에서 객체를 "할당"해야하는 경우 sizeof(SHMObject), 그리고 당신의 메모리 매니저는 그 주소를 참조하십시오 0x1ABC0000+0x1A 무료이므로 메모리 관리자가 반환해야합니다 0x1ABC001A 가치와 마크 ( 0x1ABC001A to 0x1ABC001A+sizeof(SHMObject) ) 점령되었고, 당신은 단지 캐스팅하기 만하면됩니다. SHMObject* shmObjectPtr = (SHMObject*)(0x1ABC001A);

그리고 지정된 메모리 주소 범위에서 작동하는 자신의 사용자 정의 메모리 할당자가 있다고 가정합니다.

템플릿의 경우 SHM 링 버퍼가 어떻게 보이는지 이해하지 못하지만 SHM을 사용하기 전에 그렇게했는데 내 구현은 다음과 같습니다.

//memory SHM allocator
template<typename T> class ShmRingAllocator
{
    protected:
        void* baseAddress;
    public:
        ShmRingAllocator(void* baseAddress,int memSize);
        void* allocate(); //this function do what I described earlier, or you can use placement new: new (baseAddress+offset)T;
}

//some kind of shared_ptr<> that handle object in SHM, this provides mechanishm to check is the pointer still valid in shm or not
template<typname T> ShmRingObjectPtr 
{
    protected:
         T* object; //mapped address of object at current process
         ShmBuffer* shm; //every object has pointer to which SHM does this pointer pointing at
    public:
         virtual T* operator->(); //operator overload to access T object
}

class ShmBuffer //base class for all kind of SHM buffer
{
    protected:
         std::string shmName;
         void* shmBasePtr;
}

template<typename T,class A=ShmRingAllocator<T>> ShmRingBuffer : public ShmBuffer
{
    protected:
         A allocator;
    public:
         ShmRingObjectPtr<T> insert() //push one element to ring buffer
         {
              return ShmRingObjectPtr<T>((T*)this->allocator.allocate(),this);
         }
}

`

다른 팁

나는 당신이 표준을 찾고 있다고 생각합니다 새로운 배치.

만약에 shm_addr a void* 공유 메모리에 대한 포인터 :

MyBuffer *pBuf = new (shm_Addr) MyBuffer;

그리고 새로운 MyBuffer 주어진 위치에 건설됩니다. 이것은 템플릿 유형을 포함하여 모든 유형의 객체에서 작동 할 수 있습니다.

맞는 경우 별도의 기능으로 래핑 할 수 있습니다.

표준으로 만든 것을 파괴합니다 새로운 배치 당신은 명시 적으로 소멸자를 호출해야합니다. 이 때문입니다 delete 메모리를 정기적으로 비 할당하려고합니다 new 유효한 일이 아닌 메모리를 할당했습니다. 이것은 C ++의 유일한 시간입니다. 파괴자를 명시 적으로 호출해야합니다.

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