Professional Documents
Culture Documents
Outline
22-1
22-3
22-10
22-23
22-32
22-43
Outline
22-1
22-3
22-10
22-23
22-32
22-43
Shared memory
Data is exchanged by placing it in memory pages shared
by multiple processes
Pages are in user virtual address space of each process
Process A page table
Physical memory
Pages not
actually
contiguous
c
2015,
Michael Kerrisk
22-4
22.1
Shared memory
Data transfer is not mediated by kernel
User-space copy makes data visible to other processes
Very fast IPC
c
2015,
Michael Kerrisk
22-5
22.1
Shared le mappings
Sharing between unrelated processes, backed by le in
lesystem
c
2015,
Michael Kerrisk
22-6
22.1
c
2015,
Michael Kerrisk
22-7
22.1
22-8
22.1
c
2015,
Michael Kerrisk
c
2015,
Michael Kerrisk
22-9
22.1
Outline
22-1
22-3
22-10
22-23
22-32
22-43
c
2015,
Michael Kerrisk
[TLPI 54.2]
22-12
22.2
c
2015,
Michael Kerrisk
22-13
22.2
c
2015,
Michael Kerrisk
22-14
22.2
c
2015,
Michael Kerrisk
22-15
22.2
c
2015,
Michael Kerrisk
22-16
22.2
argv, environ
Stack
(grow downward)
(unallocated memory)
Memory
mappings
allocated here
Heap
(grows upward)
Uninitialized data (bss)
Initialized data
Low virtual
address
c
2015,
Michael Kerrisk
22-17
22.2
c
2015,
Michael Kerrisk
22-18
22.2
c
2015,
Michael Kerrisk
22-19
22.2
c
2015,
Michael Kerrisk
22-20
22.2
Example: pshm/pshm_create_simple.c
./ p sh m_ cre at e_s im pl e / shm - object - name size
c
2015,
Michael Kerrisk
22-21
22.2
Example: pshm/pshm_create_simple.c
1
2
3
4
5
6
7
8
9
int fd ;
size_t size ;
void * addr ;
size = atoi ( argv [2]);
fd = shm_open ( argv [1] , O_CREAT | O_EXCL | O_RDWR,
S_IRUSR | S_IWUSR);
ftruncate (fd, size);
addr = mmap ( NULL , size, PROT_READ | PROT_WRITE,
MAP_SHARED , fd, 0);
1
c
2015,
Michael Kerrisk
22-22
22.2
Outline
22-1
22-3
22-10
22-23
22-32
22-43
c
2015,
Michael Kerrisk
[TLPI 48.6]
22-24
22.3
Example: pshm/phm_write.c
./ pshm_write / shm - name string
c
2015,
Michael Kerrisk
22-25
22.3
Example: pshm/phm_write.c
1
2
3
4
5
6
7
8
9
10
11
12
int fd ;
size_t len ;
/* Size of shared memory object */
char * addr ;
fd = shm_open( argv [1] , O_RDWR , 0);
len = strlen ( argv [2]);
ftruncate( fd , len);
printf ( " Resized to % ld bytes \ n " , ( long ) len );
addr = mmap(NULL, len , PROT_READ | PROT_WRITE ,
MAP_SHARED , fd , 0);
close ( fd );
/* fd is no longer needed */
printf ( " copying % ld bytes \ n " , ( long ) len );
memcpy(addr, argv[2], len);
1
2
3
4
5
c
2015,
Michael Kerrisk
22-26
22.3
Example: pshm/phm_read.c
./ pshm_read / shm - name
c
2015,
Michael Kerrisk
22-27
22.3
Example: pshm/phm_read.c
1
2
3
4
5
6
7
8
9
10
11
12
13
int fd ;
char * addr ;
struct stat sb ;
fd = shm_open(argv[1], O_RDONLY , 0);
fstat( fd , & sb );
addr = mmap( NULL , sb.st_size, PROT_READ , MAP_SHARED ,
fd , 0);
close ( fd );
/* fd is no longer needed */
write(STDOUT_FILENO, addr, sb.st_size);
printf ( " \ n " );
c
2015,
Michael Kerrisk
22-28
22.3
c
2015,
Michael Kerrisk
[TLPI 48.6]
22-29
22.3
22-30
22.3
Wrong way:
* p = target
To dereference pointer:
target = baseaddr + * p ;
Linux/UNIX System Programming
c
2015,
Michael Kerrisk
c
2015,
Michael Kerrisk
22-31
22.3
Outline
22-1
22-3
22-10
22-23
22-32
22-43
c
2015,
Michael Kerrisk
22-34
22.4
c
2015,
Michael Kerrisk
22-35
22.4
Example: pshm/pshm_seqnum.h
1
2
3
4
5
6
7
8
9
10
# include
# include
# include
# include
# include
struct shmbuf {
sem_t sem ;
int seqnum ;
};
c
2015,
Michael Kerrisk
22-36
22.4
Example: pshm/pshm_seqnum_init.c
./ pshm_seqnum_init / shm - name [ init - value ]
c
2015,
Michael Kerrisk
22-37
22.4
Example: pshm/pshm_seqnum_init.c
1
2
3
4
5
6
7
8
9
4
5
c
2015,
Michael Kerrisk
22-38
22.4
Example: pshm/pshm_seqnum_get.c
./ pshm_seqnum_get / shm - name [ run - length ]
c
2015,
Michael Kerrisk
22-39
22.4
int fd , runLength ;
struct shmbuf * shmp ;
fd = shm_open( argv [1] , O_RDWR , 0);
shmp = mmap( NULL , sizeof(struct shmbuf),
PROT_READ | PROT_WRITE , MAP_SHARED , fd , 0);
c
2015,
Michael Kerrisk
22-40
22.4
Release semaphore
c
2015,
Michael Kerrisk
22-41
22.4
Exercise
1
Write two programs that exchange a stream of data of arbitrary length via a POSIX
shared memory object:
The writer (pshm_xfr_writer.c) reads blocks of data from stdin and copies
them a block at a time to the shared memory region.
The reader (pshm_xfr_reader.c) copies each block of data from the shared
memory object to stdout
You must ensure that the writer and reader have exclusive, alternating access to the
shared memory region (so that, for example, the writer does not copy new data into the
region before the reader has copied the current data to stdout). This will require the use
of a pair of semaphores. (Using two unnamed semaphores stored inside the shared
memory object is simplest, but remember that the reader will also need to map the
shared memory for writing, so that it can update the semaphores.) The
psem_tty_lockstep_init.c and psem_tty_lockstep_second.c programs provided in
the POSIX semaphores module show how semaphores can be used for this task. (Those
programs use a pair of named semaphores.)
When the writer reaches end of le, it should provide an indication to the reader that
there is no more data. To do this, maintain a byte-count eld in the shared memory
region which the writer uses to inform the reader how many bytes are to be written.
Setting this count to 0 can be used to signal end-of-le. Once it has sent the last data
block and the reader has indicated that it has consumed that block (e.g., by posting the
"writers" semaphore once more), the writer should destroy the unnamed semaphores
and unlink the shared memory object.
c
2015,
Michael Kerrisk
22-42
22.4
Outline
22-1
22-3
22-10
22-23
22-32
22-43
c
2015,
Michael Kerrisk
22-44
22.5
c
2015,
Michael Kerrisk
[TLPI 54.4]
22-45
22.5