0% found this document useful (0 votes)
64 views

ANP - 6. IPC-shared Memory

Shared memory is the fastest form of inter-process communication. It allows processes to directly access memory that is mapped into each process's address space, without needing to copy data. The mmap function maps a file or shared memory object into a process's address space. Changes made to the mapped memory by one process are visible to other processes that have the memory mapped with MAP_SHARED. The msync function can be used to explicitly synchronize changes in mapped memory with the underlying file. A program example demonstrates incrementing a counter stored in shared memory, using a semaphore also stored in the shared memory to provide synchronization between processes accessing the counter.

Uploaded by

Suman
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
64 views

ANP - 6. IPC-shared Memory

Shared memory is the fastest form of inter-process communication. It allows processes to directly access memory that is mapped into each process's address space, without needing to copy data. The mmap function maps a file or shared memory object into a process's address space. Changes made to the mapped memory by one process are visible to other processes that have the memory mapped with MAP_SHARED. The msync function can be used to explicitly synchronize changes in mapped memory with the underlying file. A program example demonstrates incrementing a counter stored in shared memory, using a semaphore also stored in the shared memory to provide synchronization between processes accessing the counter.

Uploaded by

Suman
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

7/21/2017

Shared Memory
• Shared memory is the fastest form of IPC
Inter-process Communication available.
– For example, in usage of message queue. A
(IPC):POSIX Shared Memory message gets copied from sender’s user-space to
the message queue, and from message queue to
Harshad B. Prajapati user’s space for receiver. (Copying from input and
Associate Professor sending output to output device adds two more
Information Technology Department, copying operations)
Dharmsinh Desai University, Nadiad
• After memory is mapped into the user’s
address space, there is no kernel involvement.

mmap, munmap, and msync mmap, munmap, and msync


functions functions
• mmap function • mmap function
#include <sys/mman.h>
– It maps either a file or a Posix shared memory
void* mmap(void* addr, size_t len, int prot, int flags, int fd, off_t
object into the address space of a process.
offset);
– This function can be used for following purposes – addr: it is the starting address in the calling process where the
• With a regular file for memory-mapped I/O descriptor fd should be mapped. Normally, null pointer is specified.
Return value of the function gives starting address of memory where
• With shm_open to provide Posix shared memory descriptor has been mapped.
between unrelated processes. – len: number of bytes to map into the address space of the process.
– offset: bytes starting at offset value with reference to the beginning of
the file. Normally it is 0.

mmap, munmap, and msync mmap, munmap, and msync


functions functions
void* mmap(void* addr, size_t len, int prot, int flags, int void* mmap(void* addr, size_t len, int prot, int flags, int fd, off_t
fd, off_t offset); offset);
– Flags:
– prot: The protection of memory-mapped region is
MAP_SHARED: Modifications to the mapped data by the calling process
specified using this argument. Possible values: are visible to all processes that are sharing the object, and these
PROT_READ data can be read modifications are reflected in the underlying object.
PROT_WRITE data can be written MAP_PRIVATE: Modifications to the mapped data by the calling process
PROT_EXEC data can be executed are visible only to that process and it does not change underlying file
PROT_NONE data cannot be accessed or shared memory object.
The commonly used value is PROT_READ | PROT_WRITE.
MAP_FIXED: Portable code should not specify this flag ORed with either
MAP_SHARED or MAP_PRIVATE and it should specify addr as null.
The non-null value of addr is taken as a hint about where the shared
memory should be located.

1
7/21/2017

mmap, munmap, and msync mmap, munmap, and msync


functions functions
• One way to share memory between a parent and child is to • The memory-mapped file is kept synchronized with the memory-mapped
call mmap with MAP_SHARED before fork. region in the memory, assuming MAP_SHARED, by the kernel’s virtual
memory algorithm.
– Memory mappings in the parent are retained in the child. Moreover,
changes done by the parent are visible to the child and vice versa. • If we want to perform above explicitly, use msync.
int msync(void* addr, size_t len, int flags);
• Remove the mapping from the address space of the process
• flags:
int munmap(void* addr, size_t len); MS_ASYNC: returns once the write operations are queued by the kernel.
(Return 0 on success, -1 on error) (from in memory copy to file)
– addr: It is the address returned by mmap MS_SYNC: returns only after the write operations are complete. (from in
– len: It is the size of the mapped region. memory copy to file)
After removing the mapping, further references to this address results in MS_INVALIDATE: All in memory copies (All other file mappings) of the file
SIGSEGV signal to the process. data that are inconsistent with the file data are invalidated. (from file to all
in memory copies)
– If mapped region was mapped using MAP_PRIVATE, the changes made
are discarded. Use either MS_ASYNC or MS_SYNC optionally with MS_INVALIDATE.

mmap, munmap, and msync Programs: Increment counter in


functions shared memory
• Using memory mapped file, we can access file We’ll also see synchronization using
without calling read, write or lseek system (1)semaphore is in memory and
calls. (advantage) (2)named- semaphore
• But, not all files can be memory mapped.
(don’t try to map a descriptor that refers to a
terminal or a socket, it will result in error).
(disadvantage)

Program: ShmCounterIMSem.c Program: ShmCounterIMSem.c


Program: Both counter and semaphore in shared memory int main(int argc,char** argv){
#include <stdio.h> int fd,i,nloop;
#include <unistd.h> struct shared *ptr;
#include <sys/types.h> if(argc!=3){
#include <sys/stat.h> fprintf(stderr,"Usage: %s pathname #Count\n",argv[0]);
#include <fcntl.h> exit(-1);
#include <sys/mman.h> }
#include <semaphore.h> nloop=atoi(argv[2]);
#define FILE_MODE S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH /*open file, initialize to 0, map into memory*/
struct shared{ fd=open(argv[1],O_RDWR|O_CREAT,FILE_MODE);
sem_t lock; write(fd,&shared,sizeof(struct shared));
int counter; ptr=mmap(NULL,sizeof(struct
}shared; shared),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
close(fd);

2
7/21/2017

Program: ShmCounterIMSem.c Program: ShmCounterIMSem.c


/*initialize semaphore that is shared between processes*/ /*parent*/
sem_init(&ptr->lock,MAP_SHARED,1); for(i=0;i<nloop;i++){
setbuf(stdout,NULL); sem_wait(&ptr->lock);
if(fork()==0){ printf("Parent: counter = %d\n",ptr->counter++);
//child sem_post(&ptr->lock);
for(i=0;i<nloop;i++){ sleep(1);
sem_wait(&ptr->lock); }
printf("Child: counter = %d\n",ptr->counter++); exit(0);
sem_post(&ptr->lock); }
sleep(1);
}
exit(0);
}

Compile and execute:


Program on Named Semaphore
ShmCounterIMSem.c
# gcc ShmCounterIMSem.c –o ShmCounterIMSem –lrt Counter is in Shared memory
Semaphore is a named semaphore.
(-lrt indicates required library for shared memory/semaphore
calls)
Create two programs, they differ in following ways.
1) ShmCounterNSemCreator.c
# ./ShmCounterIMSem.c /tmp/counter 4 It creates initial content of shared memory.
It creates named semaphore and initializes it.
1) ShmCounterNSemUser.c
It opens a named semaphore.

ShmCounterNSemCreator.c ShmCounterNSemCreator.c
#include <stdio.h> int main(int argc,char** argv){
#include <unistd.h> int fd,i,nloop;
#include <sys/types.h> struct shared *ptr;
#include <sys/stat.h> sem_t* lock;
#include <fcntl.h> if(argc!=4){
#include <sys/mman.h> fprintf(stderr,"Usage: %s pathname #Count semaphore-
#include <semaphore.h> name\n",argv[0]);
#define FILE_MODE S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH exit(-1);
struct shared{ }
int counter; nloop=atoi(argv[2]);
}shared;

3
7/21/2017

ShmCounterNSemCreator.c ShmCounterNSemCreator.c
/*open file, initialize to 0, map into memory*/ for(i=0;i<nloop;i++){
fd=open(argv[1],O_RDWR|O_CREAT,FILE_MODE); sem_wait(lock);
write(fd,&shared,sizeof(struct shared)); printf("Process(%d): counter = %d\n",getpid(),ptr-
ptr=mmap(NULL,sizeof(struct shared), >counter++);
PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); sem_post(lock);
close(fd); sleep(1);
/*Create a named semaphore and initialize it*/ }
lock=sem_open(argv[3], O_CREAT,FILE_MODE,1); exit(0);
setbuf(stdout,NULL); }

ShmCounterNSemUser.c ShmCounterNSemUser.c
#include <stdio.h> int main(int argc,char** argv){
#include <unistd.h> int fd,i,nloop;
#include <sys/types.h> struct shared *ptr;
#include <sys/stat.h> sem_t* lock;
#include <fcntl.h> if(argc!=4){
#include <sys/mman.h> fprintf(stderr,"Usage: %s pathname #Count semaphore-
#include <semaphore.h> name\n",argv[0]);
#define FILE_MODE S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH exit(-1);
struct shared{ }
int counter; nloop=atoi(argv[2]);
}shared;

ShmCounterNSemUser.c ShmCounterNSemUser.c
/*open file, map into memory*/ for(i=0;i<nloop;i++){
fd=open(argv[1],O_RDWR,FILE_MODE); sem_wait(lock);
ptr=mmap(NULL,sizeof(struct printf("Process(%d): counter = %d\n",getpid(),ptr-
shared),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); >counter++);
close(fd); sem_post(lock);
/*Create a named semaphore and initialize it, in this case it sleep(1);
already exists*/ }
lock=sem_open(argv[3],O_CREAT); exit(0);
setbuf(stdout,NULL); }

4
7/21/2017

Compilation and execution of both


POSIX Shared Memory
programs
# gcc ShmCounterNSemCreator.c –o ShmCounterNSemCreator –lrt
• Posix.1 provides two ways to share memory
# gcc ShmCounterNSemUser.c –o ShmCounterNSemUser –lrt between unrelated processes.
– Memory mapped files
On, one terminal execute following.
• File is opened using open
# ./ShmCounterCreator /tmp/counter 30 /lock
• Resulting descriptor is mapped using mmap.
Start a new terminal (Have two terminals opened and commands typed). – Shared memory objects
Execute following.
• Shared object is opened using shm_open.
# ./ShmCounterUser /tmp/counter 5 /lock
• It is mapped to process’s address space using mmap.

Functions Functions
• Create a new or open an existing shared memory object: • Removes a name of shared object.
#include <sys/mman.h> #include <sys/mman.h>
int shm_open(const char* name, int oflag, mode_t mode); int shm_unlink(const char* name);
– oflag: either O_RDONLY or O_RDWR. – It removes the name of shared memory object.
Other flags (optional) can also be specified – Unlinking has no effect on existing references to the underlying object,
O_CREAT or O_EXCL until all references to that object are closed. (It maintains reference
If O_TRUNC is specified along with O_RDWR flag, then if the shared count, on each close call, reference count is decremented by one.)
memory object already exists, it is truncated to 0-length.
– mode: It specifies permission bits. It is used when O_CREAT flag is
specified. It is compulsory, unlike mq_open and sem_open functions.
– The return value from shm_open is passed as the fifth argument to
the mmap.

Functions Functions
• Change size of regular file or a shared memory • Obtain information about existing shared memory object
#include <sys/types.h>
object.
#include <sys/stat.h>
#include <unistd.h> int fstat(int fd, struct stat* buf);
int ftruncate(int fd, off_t length); Following members provide information related to shared memory object.
Other members are not listed.
– For a regular file: struct stat{
• Size of file was larger than length, the extra data is discarded.

• Size of file was smaller than length, “what happens to file” is unspecified.
mode_t st_mode; /*mode:S_I{R,W}{USR,GRP,OTH}*/
Portable way to extend file size to length bytes is to lseek to offset
uid_t st_uid; /* user ID of owner*/
length-1 and write 1 byte of data.
gid_t st_gid; /* group ID of owner*/
– For a shared memory object: ftruncate sets the size of the off_t st_size; /* size in bytes */
object to length. …
};

5
7/21/2017

Program on Named Semaphore ShmCounterNSemCreator.c


Counter is in Shared memory object (get using #include <stdio.h>
shm_open) #include <unistd.h>
Semaphore is a named semaphore. (get using #include <sys/types.h>
sem_open) #include <sys/stat.h>
#include <fcntl.h>
Create two programs, they differ in following ways.
#include <sys/mman.h>
1) ShmCounterNSemCreator.c
#include <semaphore.h>
It creates initial content of shared memory. #define FILE_MODE S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
It creates named semaphore and initializes it. struct shared{
1) ShmCounterNSemUser.c int counter;
It opens a named semaphore. }shared;

ShmCounterNSemCreator.c ShmCounterNSemCreator.c
int main(int argc,char** argv){ /* open shared memory object, change it size, map into
int fd,i,nloop; memory*/
struct shared *ptr; fd=shm_open(argv[1],O_RDWR|O_CREAT,FILE_MODE);
sem_t* lock; ftruncate(fd,sizeof(struct shared));
if(argc!=4){ ptr=mmap(NULL,sizeof(struct
fprintf(stderr,"Usage: %s shm-object-name #Count shared),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
semaphore-name\n",argv[0]);
fprintf(stderr,"Ex: %s /counter 10 /lock\n",argv[0]);
exit(-1);
}
nloop=atoi(argv[2]);

ShmCounterNSemCreator.c ShmCounterNSemUser.c
/*Create a named semaphre and initialize it*/ #include <stdio.h>
lock=sem_open(argv[3], O_CREAT,FILE_MODE,1); #include <unistd.h>
setbuf(stdout,NULL); #include <sys/types.h>
for(i=0;i<nloop;i++){ #include <sys/stat.h>
sem_wait(lock); #include <fcntl.h>
printf("Process(%d): counter = %d\n",getpid(),ptr- #include <sys/mman.h>
>counter++); #include <semaphore.h>
sem_post(lock); #define FILE_MODE S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH
sleep(1); struct shared{
} int counter;
exit(0); }shared;
}

6
7/21/2017

ShmCounterNSemUser.c ShmCounterNSemUser.c
int main(int argc,char** argv){ nloop=atoi(argv[2]);
int fd,i,nloop; /*open file, map into memory*/
struct shared *ptr; fd=shm_open(argv[1],O_RDWR,FILE_MODE);
sem_t* lock; ptr=mmap(NULL,sizeof(struct
if(argc!=4){ shared),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
fprintf(stderr,"Usage: %s s shm-object-name #Count
semaphore-name\n",argv[0]);
fprintf(stderr,"Ex: %s /counter 5 /lock\n",argv[0]);
exit(-1);
}

Compilation and execution of both


ShmCounterNSemUser.c
programs
/*Create a named semaphre and initialize it, it already exists*/ # gcc ShmCounterNSemCreator.c –o ShmCounterNSemCreator –lrt
lock=sem_open(argv[3],O_CREAT);
# gcc ShmCounterNSemUser.c –o ShmCounterNSemUser –lrt
setbuf(stdout,NULL);
for(i=0;i<nloop;i++){
On, one terminal execute following.
sem_wait(lock); # ./ShmCounterCreator /counter 30 /lock
printf("Process(%d): counter = %d\n",getpid(),ptr-
>counter++); Start a new terminal (Have two terminals opened and commands typed).
sem_post(lock); Execute following.
# ./ShmCounterUser /counter 5 /lock
sleep(1);
} (Imp Note: Be Careful while specifying name of POSIX IPC objects, should
exit(0); start with slash (/) and should contain only one slash(/))
}

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy