Wednesday, June 17, 2009

Shared Memory

Posted by Sarjukottapuram

SHARED MEMORY

Theory

In computing, shared memory is a memory that may be simultaneously accessed by multiple programs with an intent to provide communication among them. Depending on context, programs may run on the same physical processor or on separate ones. Using memory for communication inside a single program, for example among its multiple threads, is generally not referred to as shared memory.
In computer software, shared memory is a method of inter-process communication (IPC), i.e. a way of exchanging data between programs running at the same time. One process will create an area in RAM which other processes can access.
Since both processes can access the shared memory area like regular working memory, this is a very fast way of communication (as opposed to other mechanisms of IPC such as named pipes, Unix sockets or CORBA). On the other hand, it is less powerful, as for example the communicating processes must be running on the same machine (whereas other IPC methods can use a computer network).
IPC by shared memory is mainly used on Unix systems.
POSIX provides a standardized API for using shared memory, POSIX Shared Memory. This uses the function shm_open from sys/mman.h.
Shared Memory is an efficeint means of passing data between programs. One program will create a memory portion which other processes (if permitted) can access.
In the Solaris 2.x operating system, the most efficient way to implement shared memory applications is to rely on the mmap() function and on the system's native virtual memory facility. Solaris 2.x also supports System V shared memory, which is another way to let multiple processes attach a segment of physical memory to their virtual address spaces. When write access is allowed for more than one process, an outside protocol or mechanism such as a semaphore can be used to prevent inconsistencies and collisions.
A process creates a shared memory segment using shmget()|. The original owner of a shared memory segment can assign ownership to another user with shmctl(). It can also revoke this assignment. Other processes with proper permission can perform various control functions on the shared memory segment using shmctl(). Once created, a shared segment can be attached to a process address space using shmat(). It can be detached using shmdt() (see shmop()). The attaching process must have the appropriate permissions for shmat(). Once attached, the process can read or write to the segment, as allowed by the permission requested in the attach operation. A shared segment can be attached multiple times by the same process. A shared memory segment is described by a control structure with a unique ID that points to an area of physical memory. The identifier of the segment is called the shmid. The structure definition for the shared memory segment control structures and prototypews can be found in .
Accessing a Shared Memory Segment
shmget() is used to obtain access to a shared memory segment. It is prottyped by:
int shmget(key_t key, size_t size, int shmflg);
The key argument is a access value associated with the semaphore ID. The size argument is the size in bytes of the requested shared memory. The shmflg argument specifies the initial access permissions and creation control flags.
When the call succeeds, it returns the shared memory segment ID. This call is also used to get the ID of an existing shared segment (from a process requesting sharing of some existing memory portion).
The following code illustrates shmget():

#include
#include
#include
...
key_t key; /* key to be passed to shmget() */
int shmflg; /* shmflg to be passed to shmget() */
int shmid; /* return value from shmget() */
int size; /* size to be passed to shmget() */
...
key = ...
size = ...
shmflg) = ...

if ((shmid = shmget (key, size, shmflg)) == -1) {
perror("shmget: shmget failed"); exit(1); } else {
(void) fprintf(stderr, "shmget: shmget returned %d\n", shmid);
exit(0);
}
...

Controlling a Shared Memory Segment

shmctl() is used to alter the permissions and other characteristics of a shared memory segment. It is prototyped as follows:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
The process must have an effective shmid of owner, creator or superuser to perform this command. The cmd argument is one of following control commands:
SHM_LOCK -- Lock the specified shared memory segment in memory. The process must have the effective ID of superuser to perform this command.
SHM_UNLOCK -- Unlock the shared memory segment. The process must have the effective ID of superuser to perform this command.
IPC_STAT-- Return the status information contained in the control structure and place it in the buffer pointed to by buf. The process must have read permission on the segment to perform this command.
IPC_SET-- Set the effective user and group identification and access permissions. The process must have an effective ID of owner, creator or superuser to perform this command.
IPC_RMID -- Remove the shared memory segment.
The buf is a sructure of type struct shmid_ds which is defined in

Program
Server

/*Program to demonstrate the use of shared memory in interprocess communication.
* This program acts as a server which waits for a message from the client process.
* The process is implemented using a shared memory space called 'shared_location'.
* The 'message' part of this space stores the message while the 'written' part is used to indicate whether the server has read the message or the client has written the message.(0->read,1->written).
* This module should be compiled and executed first.
* This module is compile using 'cc shmserver.c' and executed using './a.out'*/

//inculsion
#include
#include
#include
#include
#include
#include

//structure definition for acquiring a shared location.
struct shared_location
{
int written;
char message[30];
};
int main()
{
int shmid,running;
void *address;
struct shared_location * ptr;

//for getting a shared location
shmid=shmget((key_t)1234,sizeof(struct shared_location),0666|IPC_CREAT);

//optional if required for error checking.
if(shmid<=0) { printf("\nERROR:\tCannot allocate shared space.\n"); exit(0); } //attaching the shared location to this process.
address=shmat(shmid,(void *)0,0); //optional if required for error checking.
if(address==(void*)0) { printf("\nEROOR:\tShared location cannot be attached.\n"); } //type casting so as to convert the obyained location into our format.
ptr=(struct shared_location*)address; ptr->written=0;
strcpy(ptr->message,"Hi I am server.");
running=1;
while(running)
{
printf("\nWaiting for the client to enter the message.\n");

while(ptr->written==0)
{
}
if(ptr->written==1)
{
printf("The client has entered the message: %s\n",ptr->message);
}
ptr->written=0;
if(strcmp(ptr->message,"end")==0)
{
running=0;
}
}

//detaching the shared location.
shmdt(address);

//deleting the shared location.
shmctl(shmid,IPC_RMID,NULL);
}

Output

Client

Program

/* Program to demonstrate the use of shared memory in interprocess communication.
* This module acts as a client which sends messages to the server process.
* In this the message entered into the message part of the 'shared_location' structure and the 'written' field is set to 1.
* The remaining process is similar to that of the server process.
* This module can be compiled using 'cc shmclient.c -o b' and executed using './b'

//inculsion
#include
#include
#include
#include
#include
#include

//structure definition for the shared location.
struct shared_location
{
int written;
char message[30];
};

//the functions and other terms used have similar meanings to that used in the server module
 //but they don't bear any specific relationship.
int main()
{
int shmid,running;
void *address;
struct shared_location * ptr;
shmid=shmget((key_t)1234,sizeof(struct shared_location),0666|IPC_CREAT);
if(shmid<=0)
{
printf("\nERROR:\tCannot allocate shared memory.\n");
exit(0);
}
address=shmat(shmid,(void*)0,0);
if(address==(void*)0)
{
printf("\nERROR:\tCannot attach the shared location\n");
exit(0);
}
ptr=(struct shared_location*)address;
running=1;
while(running)
{
printf("\nWaiting for the server\n");
while(ptr->written==1)
{
}
printf("\nEnter your message.(type 'end' to exit)\n");
scanf("%s",ptr->message);
ptr->written=1;
if(strcmp(ptr->message,"end")==0)
{
running=0;
}
}
address=shmat(shmid,(void *)0,0);
shmdt(address);
}

Output

0 comments:

Post a Comment