• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 291
  • Last Modified:

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
0
yairy
Asked:
yairy
  • 6
  • 3
  • 2
1 Solution
 
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
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
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

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

  • 6
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now