إضافة مصلح إلى قالب فئة C ++ لإنشاء كائن الذاكرة المشتركة

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

  •  19-09-2019
  •  | 
  •  

سؤال

باختصار سؤالي هو: إذا كان لديك فئة، MyClass<T>, ، كيف يمكنك تغيير تعريف الفصل لدعم الحالات التي لديك MyClass<T, Alloc>, ، على غرار كيف، يقول، يوفر STL ناقلات.

أحتاج إلى هذه الوظيفة لدعم مصلح للذاكرة المشتركة. على وجه التحديد، أحاول تنفيذ مخزن مؤقت حلقة في الذاكرة المشتركة. حاليا لديها الطاولة التالية:

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);

ومع ذلك، لا أعرف كيف أذهب حول إضافة مصلح صريح إلى قالب الفصل.

هل كانت مفيدة؟

المحلول

ما الذي يجعلني مرتبكا هو، لماذا تحتاج إلى تخصيص أو إنشاء كائن في SharedMemory (SHM)، على سبيل المثال إذا قمت بإحالة ذاكرة مشتركة لحجم 65536 بايت، فافترض أنك تحصل على ذاكرة مشتركة في العنوان 0x1ABC0000, ، إذا كان نجاح الحجز سيكون لديك مساحة ذاكرة مجانية ويمكن الوصول إليها مباشرة في 0x1ABC0000 to 0x1ABCFFFF.

ثم عندما يحتاج طلبك إلى "تخصيص" كائن في SHM الحجم sizeof(SHMObject), ، ومدير ذاكرة الخاص بك يرى هذا العنوان في 0x1ABC0000+0x1A مجاني، يجب أن يعود مدير الذاكرة الخاص بك فقط 0x1ABC001A القيمة، والعلامة ( 0x1ABC001A to 0x1ABC001A+sizeof(SHMObject) ) كانت محتلة، وتحتاج فقط إلى الإدلاء: SHMObject* shmObjectPtr = (SHMObject*)(0x1ABC001A);

وفك ofchourse الذي يفترض أن يكون لديك مخصص الذاكرة المخصصة الخاصة بك يعمل على نطاق محدد من عنوان الذاكرة.

أما بالنسبة للقالب، فأنا لا أفهم حقا كيف تبدو المخزن المؤقت الدائري الخاص بك، لكنني فعلت ذلك قبل استخدام 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 هو void* مؤشر إلى الذاكرة المشتركة يمكنك القيام به:

MyBuffer *pBuf = new (shm_Addr) MyBuffer;

والجديد MyBuffer سيتم بناؤها في الموقع المحدد. هذا يمكن أن يعمل مع أي نوع من الأشياء، بما في ذلك أنواع القسم.

يمكنك التفاف هذا في وظيفة منفصلة إذا رأيت مناسبا.

لتدمير شيء خلق مع المعيار التنسيب جديد تحتاج إلى الاتصال صراحة بالمدير. هذا بسبب delete سيحاول إلغاء تخصيص الذاكرة منتظمة new الذاكرة المخصصة التي لن تكون شيئا صالحا للقيام به. هذه هي المرة الوحيدة في C ++ التي تحتاج إليها لاستدعاء المدمرة بشكل صريح.

pBuf->~MyBuffer();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top