Chapter Contents

Previous

Next
shmat

shmat



Attach a Shared Memory Segment

Portability: UNIX compatible


SYNOPSIS
DESCRIPTION
RETURN VALUE
USAGE NOTES
EXAMPLE 1
EXAMPLE 2
RELATED FUNCTIONS


SYNOPSIS

#include <sys/shm.h>
void *shmat(int id, const void *addr,
            int flags);


DESCRIPTION

The shmat function is used to attach a shared memory segment to a process, so that the memory contents can be accessed.

Note:   See the shmget function description in section shmget for general information about shared memory segments.  [cautionend]
The id argument to shmat specifies a shared memory segment id. This argument is an id, such as the id returned by shmget , not a memory segment key, which might be passed as an argument to shmget .

The addr argument to shmat specifies a pointer value indicating the address at which the memory segment is to be attached. If addr is NULL , the segment will be attached at an address selected by the system. If addr is specified, shmat will fail if the segment cannot be attached as specified because memory is already allocated near the address specified.

Note:   The flag bit SHM_RND influences the interpretation of addr , as described below.  [cautionend]
The flags argument specifies zero or more option flags. The argument should be specified as 0 for no flags, or as one or more of the following symbolic constants, combined using the or operator (|):


RETURN VALUE

shmat returns the address of the attached segment, or (void *) -1 if unsuccessful.


USAGE NOTES

The shmat function can only be used with MVS 5.2.2 or a later release.

Note:   A site can impose limits on the size and number of shared memory segments that can be attached.  [cautionend]


EXAMPLE 1

This example is compiled using sascc370 -Krent -o . This program uses the functions shmat() , shmctl() , shmdt() , and shmget() to establish an IPC Client using a Shared Memory Segment.

/*-------------------------------------+
| POSIX/UNIX header files              |
+-------------------------------------*/
#include <fcntl.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include sys/shm.h>

/*-------------------------------------+
| ISO/ANSI header files                |
+-------------------------------------*/
#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <errno.h>

/*-------------------------------------+
| Constants                            |
+-------------------------------------*/
/* memory segment character value     */
#define MEM_CHK_CHAR        '*'     

/* shared memory key                  */
#define SHM_KEY      (key_t)1097    

#define SHM_SIZE     (size_t)256    

/* size of memory segment (bytes)     */
/* give everyone read/write           */
/* permission to shared memory        */
#define SHM_PERM  (S_IRUSR|S_IWUSR
  |S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

/*------------------------------------+
| Name:      main                     |
| Returns:   exit(EXIT_SUCCESS) or    |
|            exit(EXIT_FAILURE)       |
+------------------------------------*/
int main()
{
/* loop counter                       */
    int i;                      

/* shared memory segment id           */
    int shMemSegID;             

/* shared memory flags                */
    int shmFlags;               

/* ptr to shared memory segment       */
    char * shMemSeg;            

/* generic char pointer               */
    char * cptr;                

/*-------------------------------------*/
/* Get the shared memory segment for   */
/* SHM_KEY, which was set by           */
/* the shared memory server.           */
/*-------------------------------------*/
   shmFlags = SHM_PERM;

if ( (shMemSegID = 
shmget(SHM_KEY, SHM_SIZE, shmFlags)) < 0 )
   {
   perror("CLIENT: shmget");
   exit(EXIT_FAILURE);
   }

/*-----------------------------------------*/
/* Attach the segment to the process's     */
/* data space at an address                */
/* selected by the system.                 */
/*-----------------------------------------*/
shmFlags = 0;
if ( (shMemSeg = 
      shmat(shMemSegID, NULL, shmFlags)) == 
      (void *) -1 )
   {
       perror("SERVER: shmat");
       exit(EXIT_FAILURE);
   }

/*-------------------------------------------*/
/* Read the memory segment and verify that   */
/* it contains the values                    */
/* MEM_CHK_CHAR and print them to the screen */
/*-------------------------------------------*/
for (i=0, cptr = shMemSeg; i < SHM_SIZE; 
i++, cptr++)
   {
      if ( *cptr != MEM_CHK_CHAR )
      {
         fprintf(stderr, "CLIENT: 
           Memory Segment corrupted!\n");
         exit(EXIT_FAILURE);
      }

      putchar( *cptr );
/* print 40 columns across            */

      if ( ((i+1) % 40) == 0 )        
     {
         putchar('\n');
      }
   }
   putchar('\n');

/*--------------------------------------------*/
/* Clear shared memory segment.               */
/*--------------------------------------------*/
   memset(shMemSeg, '\0', SHM_SIZE);

/*------------------------------------------*/
/* Call shmdt() to detach shared            */
/* memory segment.                          */
/*------------------------------------------*/
   if ( shmdt(shMemSeg) < 0 )
   {
       perror("SERVER: shmdt");
       exit(EXIT_FAILURE);
   }

   exit(EXIT_SUCCESS);

}  /* end of main() */


EXAMPLE 2

This example is compiled using sascc370 -Krent -o . This program uses the functions shmat() , shmctl() , shmdt() , and shmget() to establish an IPC Server using a Shared Memory Segment.

/*--------------------------------------+
| POSIX/UNIX header files               |
+--------------------------------------*/
#include <sys/types.h>

#include <unistd.h>

#include <fcntl.h>

#include <sys/ipc.h>

#include >sys/shm.h>

/*--------------------------------------+
| ISO/ANSI header files                 |
+--------------------------------------*/
#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <time.h>

#include <errno.h>

/*--------------------------------------+
| Constants                             |
+--------------------------------------*/
/* value to fill memory segment        */
#define MEM_CHK_CHAR         '*'    

/* shared memory key                   */
#define SHM_KEY      (key_t)1097    

/* size of memory segment (bytes)      */
#define SHM_SIZE     (size_t)256    

/* give everyone read/write permission   */
/* to shared memory                      */
#define SHM_PERM  (S_IRUSR|S_IWUSR
  |S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

/*----------------------------------------+
| Name:      main                         |
| Returns:   exit(EXIT_SUCCESS) or        |
|            exit(EXIT_FAILURE)           |
+-----------------------------------------*/
int main()
{
/* shared memory segment id           */
    int shMemSegID;             

/* shared memory flags                */
    int shmFlags;               

/* ptr to shared memory segment       */
    char * shMemSeg;            

/*---------------------------------------*/
/* Create shared memory segment          */
/* Give everyone read/write permissions. */
/*---------------------------------------*/
   shmFlags = IPC_CREAT | SHM_PERM;

 if ( (shMemSegID = 
  shmget(SHM_KEY, SHM_SIZE, shmFlags)) < 0 )
   {
       perror("SERVER: shmget");
       exit(EXIT_FAILURE);
   }

/*-------------------------------------------*/
/* Attach the segment to the process's data  */
/* space at an address                       */
/* selected by the system.                   */
/*-------------------------------------------*/
shmFlags = 0;
if ( (shMemSeg = 
      shmat(shMemSegID, NULL, shmFlags)) == 
  (void *) -1 )
   {
       perror("SERVER: shmat");
       exit(EXIT_FAILURE);
   }

/*-------------------------------------------*/
/* Fill the memory segment with MEM_CHK_CHAR */
/* for other processes to read               */
/*-------------------------------------------*/
   memset(shMemSeg, MEM_CHK_CHAR, SHM_SIZE);

/*-----------------------------------------------*/
/* Go to sleep until some other process changes  */
/* first character                               */
/* in the shared memory segment.                 */
/*-----------------------------------------------*/
   while (*shMemSeg == MEM_CHK_CHAR)
   {
      sleep(1);
   }

/*------------------------------------------------*/
/* Call shmdt() to detach shared memory segment.  */
/*------------------------------------------------*/
   if ( shmdt(shMemSeg) < 0 )
   {
       perror("SERVER: shmdt");
       exit(EXIT_FAILURE);
   }


/*--------------------------------------------------*/
/* Call shmctl to remove shared memory segment.     */
/*--------------------------------------------------*/
   if (shmctl(shMemSegID, IPC_RMID, NULL) < 0)
   {
       perror("SERVER: shmctl");
       exit(EXIT_FAILURE);
   }
 
   exit(EXIT_SUCCESS);

}  /* end of main() */


RELATED FUNCTIONS

shmctl , shmdt , shmget


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.