Chapter Contents |
Previous |
Next |
shmat |
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.
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.
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 (|):
SHM_RDONLY
-
Specifies that the segment is attached read-only, that is, the process will
be able to read the memory contents, but not change them.
SHM_RND
-
Specifies that the address specified by
addr
will be rounded down to a multiple of the page size. The page
size is defined by the symbolic constant
SHMLBA
.
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.
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 |
Chapter Contents |
Previous |
Next |
Top of Page |
Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.