Низкоуровневая реализация межпроцессных буферов

  !   Данная информация предназначена только только для IT-специалистов по системной интеграции модулей БИОСОФТ-М. (см. Руководства пользователя к программным продуктам)

Для разделяемой между процессами памяти есть низкоуровневый класс, использование которого без базовых теоретических знаний паралельного программирования и практического опыта оного приведет к гарантированным дефектам трудновыявляемого характера.

Более безопасная альтернатива для часто встречающегося случая: Разделяемый буфер для передачи потоков сигналов между процессами. Циклический

CInterMem

Написал коментариев, которых все равно абсолютно недостаточно чтобы использовать класс безопасно!

//
 // CInterMem - Interprocess Shared Memory
 //
 //   WARNING: This is a low-level object which is NOT protected automatically
 //            from common lock problems, deadlocks and race conditions!
 //            You MUST follow one of proven init scenarios to access the memory.
 //
 //   Note template<> CInterMem* classes which provide a somewhat safer way 
 //     of sharing and automatically locking the data structures in simple cases.
 //
 //   Common safe init sequence:
 //
 //   1) Call SetName() with a string constant unique to your app.
 //        All CInterMem objects in the system with the same name 
 //        will refer to the same physical memory block.
 //        This name is also used as the base for a mutex name for
 //        locking exclusive access to the memory.
 //
 //      Include the data format version in the name. Otherwise you are
 //        going to get some obscure bugs when different versions of your app 
 //        are running together!
 //
 //   ---- at this point memory is not allocated yet! ----
 //
 //   2) Call Lock() or create a local CInterMem::LOCK object 
 //        to safely initialize the buffer with FillOnFirstAllocation()
 //        later.
 //        (Do NOT call FillOnFirstAllocation() yet!)
 //        You must also lock now if you intend to use !IsAlreadyExisted()
 //        as a valid initialization condition.
 //        (Note how template<>s help you to init and lock in one step.)
 //
 //        (You may find working examples where this lock call is missing.
 //        This might not be a bug but a dangerous reliance on a 
 //        strict process intercommunication sequence which is assumed 
 //        or verified using other means.
 //        Do NOT try to pull such a trick unless you know exactly 
 //        what you are doing and what the consequences are!)
 //        
 //   3) Call SetSize() to allocate the memory.
 //        All shared CInterMem objects with the same name must 
 //        have equal size.
 //        (Although theoretically subsequent allocs may be able to 
 //        succeed allocating smaller memory blocks than the one allocated 
 //        first but do NOT try to rely on this in a volatile multiprocess
 //        environment!)
 //
 //   4) Init the buffer with FillOnFirstAllocation() for simple byte-fill init.
 //        For more complex init check IsAlreadyExisted() while still 
 //        locked (see (2)) and if shared memory had NOT existed before 
 //        the moment you had locked, then get the pointer and 
 //        init ALL bytes as appropriate to you application.
 //        (Note how template<>s help you to init and lock in one step.)
 //
 //   5) Unlock if locked on the step (2) or allow LOCK destructor to release
 //        the mutex.
 //
 //   6) Access the memory for reading and writing always checking pointers
 //        for NULL and never forget to ensure proper synchronization! 
 //        (Lock()/LOCK in most cases)
 //
 
 class CInterMem : public object
 {
     void cx_flag_IgnoreOverloads();
 
 public:
     CX_STATIC_CLASS_INFO(CInterMem);
     CInterMem();
     CInterMem( // for use only by templates, ignore this, call methods!
             str name,
             int init_size = 0,
             int lock_timeout = 0);
     ~CInterMem();
     virtual void OnExposeContent(CExpose* pExpose);
 
     // Name of a unique shared memory mapped file
     //   All CInterMem objects with the same name refer to the same 
     //   physical memory block.
     //   (Also used for internal mutex)
     // Example: "MyXxxxAppSignalArray_v2"
     void SetName(
             str name);
 
     // All shared CInterMem objects with the same name must 
     //   have equal size.
     bool SetSize(
             int size);
 
     // By default shared memory is not initialized!
     //   YOU MUST LOCK THE BUFFER AFTER SetName()!
     void FillOnFirstAllocation(
             char byte);
 
     // UNSAFE! May leak memory!
     void DetachHandle();
 
     // Make sure only single client accesses the shared buffer.
     //   This is an essential synchronization measure but it is
     //   NOT ALWAYS ENOUGH to ensure currect data access in an 
     //   application sharing multiple interdependent memory blocks.
     void Lock(
             int timeout);
     void Unlock();
 
     // To ensure we do not forget to Unlock it is more reliable 
     //   to use a local LOCK object with the unlocking destructor.
     class LOCK
     {
     public:
         LOCK(CInterMem* m, int timeout);
         ~LOCK();
         CInterMem* mem;
     };
 
     // Get attributes
     str GetName() const;
     int GetSize() const;
     int IsAlreadyExisted();
 
     // May return NULL on failure
     //   DO NOT FORGET TO LOCK THE MEMORY!
     const char* _unsafe_GetPointer() const;
     char* _unsafe_GetPointer();
 
 };
 
...
Средства блокировки

Встроены в этот класс так что отдельных мутексов создавать не требуется.

Примеры, применения и опасности

Я буду по мере надобности обертывать его использование в практические прикладные примеры на все случаи жизни. см. 1й пост.