Sheard memory functions in unix

Does anybody have some simple source code using
the sheard memory functions (shmem) in Unix OS up to the point
we allocate memory for a structre ?

Yair
LVL 2
yairyAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

aperdonCommented:
Shared memory in Unix is quite simple.

The following functions are available

shmget - create/open segment
shmat  - attach segment to process space
shmdt  - detach segment
shmctl - control segment (delete)

I dont know exactly how it works, but it goes something like this.

id = shmget(code,O_CREAT | 0x666,size)
address = shmat(id)

the retreived address can be used to store your date. allocation is done through the shmget-call.

if meanwhile you dont accept any answer i'm willing to send you an example. i dont have the source here at this place, but can have it tomorrow if you want. this source is a kind of abstraction above the shared-memory functions. it will help you a lot i promise!!

Alexander.
0
aperdonCommented:
Btw. I know exactly how it goes, but it is not direclty available in my head, but i know the concepts.
0
ufolk123Commented:
A wroking example is

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <stdlib.h>
#include <windows.h>

/* Put this declaration in some header file included in both progs */

typedef struct sharedss{
int i;
int j;
}
/********************************************************************/



main()
{
      int id, ret;
      int size;
      int perm = 0666;
      key_t key ;
      char *addr;
            struct shmid_ds  buf ;
        sharedss* MyAdd,MyData;

      MyData.i=10;
      MyData.j=20;
        MyAdd=&MyData;

       key = 1126;
       size = siezof(sharedss);

       if ((id=shmget(key, size, IPC_CREAT | perm))== -1)
       {
       printf("shmget (key:0x%x,size:%d,perm:0x%x. pid:%ld)\n",
                         key, size, perm,getpid());
      printf("errno = %d\n", errno);
       }
       else
       {
      printf("id = %d\n", id);

       }

       if ((addr = (char *)shmat(id, (char *)NULL, NULL)) == (char *)-1)
       {
      printf("shmat pas OK\n");
       }

      memcpy(addr,MyAdd,sizeof(MyData));
      Sleep(100);
       
       if ((ret=shmctl(id, IPC_RMID, NULL))== -1)
       {
       printf("shmctl pas OK \n");                  
      printf("errno = %d\n", errno);
       }
       else
       {
      printf("ret = %d\n", ret);
       }
}


Second process :
==============


#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <stdlib.h>
#include <windows.h>

main()

{
      int id, ret;
      int size;
      int perm = 0666;
      key_t key ;
      char *addr;
      sharedss* SData;
 
       key = 1126;
       size = sizeof(sharedss);

       if ((id=shmget(key, size,  IPC_CREAT | perm)) == -1)
       {
       printf("shmget (key:0x%x,size:%d,perm:0x%x. pid:%ld)\n",
                         key, size, perm,getpid());
      printf("errno = %d\n", errno);
       }
       else
       {
      printf("id = %d\n", id);
       }

      /* Attach shared memory segment */

       if ((addr = (char *)shmat(id, (void *)0, 0)) == (char *)-1)       /* Doesn't                                                       work */
       {                                                      /* With                                                 SHM_RDONLY on third
                                                parameter it works                                                              */      
      printf("shmat error\n");
      printf("errno = %d\n", errno);
      exit(0);
       }
 
       /* Read addr */
 
       printf("addr = %x %d\n", addr, *addr);
      
      SData=(sharedss*)(add);
      /**** Use it here *****/

       if ((ret=shmctl(id, IPC_RMID, NULL)) == -1)
       {
       printf("shmctl pas OK \n");                  
      printf("errno = %d\n", errno);
       }
       else
       {
      printf("ret = %d\n", ret);
       }
}

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

yairyAuthor Commented:
I thought that after you attach
the segment to the process, you can
use simple new / malloc functions.
Am I wrong ?
0
ufolk123Commented:
Hi yeiry,

The purpose of shared memory is to allocate you a chunk from the global
memory pool.Nobody actually owns this chunk.But it will get mapped in the address
space of each process opening a reference to it (shmget).Now then on
 you can use it to communicate with other processes.As it not a
process specific data area (as heap ) so you can not do free/malloc on it
which are C RTL functions defined to allocate from the process heap area.

0
aperdonCommented:
Ufolk123, YOU SUCK!! You answer what i commented. stealing points......

yairy, please reject his answer. here is the promised source. this source is used during my last project. i wont compile, but i will give you a very nice overview of shared memory in Unix.

Alex.

..h:
#ifndef MEMORY_H


typedef struct
{
      void                        *pMemory;
      int                        iMemory;
} tMemory;


/* prototypes */

extern tMemory mMEM_Create(
      int                        iKey,
      int                        iSize,
      int                        iAccess = 0660,
      bool                        bExclusive = true,
      void                        *pAttach = NULL,
      int                        iAttach = 0);

extern tMemory mMEM_Open(
      int                        iKey,
      int                        iAccess = 0660,
      void                        *pAttach = NULL,
      int                        iAttach = 0);

extern void *pMEM_GetAddress(
      tMemory                  mMemory);

extern void MEM_Resize(
      tMemory                  mMemory,
      int                        iSize);

extern void MEM_Close(
      tMemory                  mMemory);

extern void MEM_Delete(
      tMemory                  mMemory);

extern void MEM_DeleteExist(
      int                        iKey);


#define MEMORY_H
#endif

/* eof */


..cpp:
#include "bool.h"

#include <sys/shm.h>
#include <errno.h>

#include "log.h"
#include "trace.h"
#include "error.h"

#include "memory.h"


/* implementation */

tMemory mMEM_Create(
      int                        iKey,
      int                        iSize,
      int                        iAccess,
      bool                        bExclusive,
      void                        *pAttach,
      int                        iAttach)
{
      int                        iFlag;
      int                        iResult;
      void                        *pAddress;
      tMemory                  mResult;

      mResult.pMemory = NULL;
      mResult.iMemory = -1;
      
      if (iSize <= 0)
      {
            THROW_STR("MEM_Create - Invalid size");
      }

      if (iAccess > 0777)
      {
            THROW_STR("MEM_Create - Invalid access flag");
      }

      iFlag = IPC_CREAT | iAccess;
      if (bExclusive)
      {
            iFlag |= IPC_EXCL;
      }

      iResult = shmget(iKey,iSize,iFlag);
      if (iResult == -1)
      {
            THROW_SYSTEM("memory","MEM_Create - shmget");
      }
      mResult.iMemory = iResult;

      pAddress = shmat(iResult,pAttach,iAttach);
      if (pAddress == NULL)
      {
            (void)shmctl(iResult,IPC_RMID,NULL);
            mResult.iMemory = -1;
            THROW_STR("MEM_Create - shmat");
      }
      mResult.pMemory = pAddress;

      return mResult;
}

tMemory mMEM_Open(
      int                        iKey,
      int                        iAccess,
      void                        *pAttach,
      int                        iAttach)
{
      int                        iFlag;
      int                        iResult;
      void                        *pAddress;
      tMemory                  mResult;

      mResult.pMemory = NULL;
      mResult.iMemory = -1;
      
      if (iAccess > 0777)
      {
            THROW_STR("MEM_Open - Invalid access flag");
      }

      iFlag = iAccess;
      iResult = shmget(iKey,0,iFlag);
      if (iResult == -1)
      {
            THROW_STR("MEM_Open - shmget");
      }
      mResult.iMemory = iResult;

      pAddress = shmat(iResult,pAttach,iAttach);
      if (pAddress == NULL)
      {
            (void)shmctl(iResult,IPC_RMID,NULL);
            mResult.iMemory = -1;
            THROW_STR("MEM_Open - shmat");
      }
      mResult.pMemory = pAddress;

      return mResult;
}

void *pMEM_GetAddress(
      tMemory                  mMemory)
{
      if (mMemory.pMemory == NULL)
      {
            THROW_ASSERT(0,"memory not initialized");
      }

      return mMemory.pMemory;
}

void MEM_Resize(
      tMemory                  mMemory,
      int                        iSize)
{
      struct shmid_ds sdResize;
      int                        iResult;

      if (iSize <= 0)
      {
            THROW_STR("MEM_Create - Invalid size");
      }

      sdResize.shm_segsz = iSize;
      iResult = shmctl(mMemory.iMemory,SHM_SIZE,&sdResize);
      if (iResult != 0)
      {
            THROW_SYSTEM("memory","resize");
      }

      return;
}

void MEM_Close(
      tMemory                  mMemory)
{
      int                        iResult;

      if (mMemory.pMemory != NULL)
      {
            iResult = shmdt(mMemory.pMemory);
      }
      mMemory.pMemory = NULL;
      mMemory.iMemory = -1;

      return;
}

void MEM_Delete(
      tMemory                  mMemory)
{
      int                        iResult;
      struct shmid_ds dummy;

      if (mMemory.pMemory != NULL)
      {
            iResult = shmdt(mMemory.pMemory);
      }
      mMemory.pMemory = NULL;

      if (mMemory.iMemory != -1)
      {
            iResult = shmctl(mMemory.iMemory,IPC_RMID,&dummy);
            if (iResult != 0)
            {
                  THROW_SYSTEM("memory","shmctl");
            }
            mMemory.iMemory = -1;
      }

      return;
}

void MEM_DeleteExist(
      int                        iKey)
{
      tMemory                  mMemory;

      try
      {
            mMemory = mMEM_Open(iKey);
      }
      catch(...)
      {
            return;
      }
      
      MEM_Delete(mMemory);

      return;
}


/* eof */

0
aperdonCommented:
#include <windows.h>

what a **** example!!!!
your example sucks

windows on Unix, ha ha ha ha, how stupid....
0
ufolk123Commented:
aperdon,

OK I was my mistake to put< windows.h >in that code but otherwise the code is OK.
You should not complain as yriary had asked for a source code example illustrating use of storing structures.
Anyway you should not be so rude for this.
If will myself withdraw my answer if yairy agrees on it.He can reject it if he wants.
You do not have any right to comment on my answer.Please keep your emotions with yourself.

0
aperdonCommented:
It has nothing to do with emotions. But I donot like to spent half an hour to find some missing source, and someone else get the points. You should commented it instead of answering it.

But how you can be sure the code is OK? Did you compile and test it. It cant compile.

Mine code is nice. It shows you which steps to take in order to perform some shared memory functions. Remove the includes and rewrite THROW... into throw and it will compile.

The server will do: MEM_Create, GetAddress and read the info at that address.
The client will do: MEM_Open, GetAddress and store the info at that address.

Btw. be sure of synchronisation....
0
yairyAuthor Commented:
Ufolk123 gets the points.
I don't think the nature of this pannel is to fight on points.

I myself an Experts and I never seen such a behiaver.

Yair



0
aperdonCommented:
You shouldn't accepted his answer then also. For me I donot mind the points. But I dont like one gives answers while knowing someone else already is busy with it. In mine opinion ufolk shouldnot have been rewared for such bad attitude.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.