The previous section introduced the knowledge about System V shared memory. Now let's take a look at POSIX shared memory and functions.
Shared Memory is simply a real physical memory area. Some functions can be used to map this area to the address space of the process for read/write, the difference between POSIX shared memory and System V shared memory is that it is implemented by the Virtual File System (tmpfs) and has been mounted under/dev/SHM. MAN 7 shm_overview
Next let's take a look at the series of functions. Add the-LRT option during compilation, that is, connect to the librt Library (Real-time library)
Function: used to create or open a shared memory object.
Prototype int shm_open (const char * Name, int Oflag, mode_t mode );
Parameters
Name: name of the shared memory object. It must start with "/" and cannot be followed by "/". For example, the length of "/somename" cannot exceed name_max (255)
Oflag: similar to the open function, it can be o_rdonly, o_rdwr, o_creat, o_excl, and o_trunc.
Mode: this parameter always needs to be set. If Oflag does not specify o_creat, it can be set to 0.
Returned value: the non-negative integer file descriptor is returned successfully;-1 is returned if the operation fails.
Note that the shm_close function does not exist. You can use close to close the file descriptor directly.
Function: Modify the size of shared memory objects. Unlike shmget, shm_open can set the size of shared memory, but ftruncate can be used to set the size.
Prototype int ftruncate (int fd, off_t length );
Parameters
FD: file descriptor
Length: Length
Return Value: 0 is returned for success;-1 is returned for failure.
Function: obtains information about shared memory objects.
Prototype
Int fstat (int fd, struct stat * BUF );
Parameters
FD: file descriptor
Buf: returns the shared memory status.
Return Value: 0 is returned for success;-1 is returned for failure.
Struct stat can be found here.
Similar to shm_ctl (, ipc_stat ,);
Function: delete a shared memory object.
Prototype int shm_unlink (const char * Name );
Parameters
Name: name of the shared memory object
Return Value: 0 is returned for success;-1 is returned for failure.
Shm_unlink is similar to shm_ctl (, ipc_rmid ,);
Function: maps shared memory objects to the process address space.
Prototype void * MMAP (void * ADDR, size_t Len, int Prot, int flags, int FD, off_t offset );
Parameters
ADDR: the starting address to be mapped. It is usually specified as null to allow the kernel to automatically select
Len: number of bytes mapped to the process address space
Prot: ing protection mode
Flags: Flag
FD: file descriptor
Offset: the offset starting from the file header.
Returned value: the start address of the mapped memory zone is returned successfully;-1 is returned if the operation fails.
Previously, I introduced the role of the MMAP function to map files to the process address space. In fact, it can also map shared memory objects to the process address space, similar to the role of shmat, only the input file descriptor FD is returned by shm_open. Similarly, munmap can be used for un ing, similar to shmdt.
.
Below are a few programs to demonstrate:
Shm_open.c
C ++ code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
# Include <stdio. h> # Include <stdlib. h> # Include <sys/IPC. h> # Include <sys/types. h> # Include <unistd. h> # Include <errno. h> # Include <fcntl. h> # Include <sys/STAT. h> # Include <sys/Mman. h># Define err_exit (m )\ Do {\ Perror (m );\ Exit (exit_failure );\ } While (0) Int main (void) { Int shmid; Shmid = shm_open ("/XYZ", o_creat | o_rdwr, 0666 ); If (shmid =-1) Err_exit ("shm_open "); If (ftruncate (shmid, 36) =-1) Err_exit ("ftruncate "); Struct stat Buf; If (fstat (shmid, & BUF) =-1) Err_exit ("fstat "); Printf ("size = % lD, mode = % O \ n", Buf. st_size, Buf. st_mode & 0777 ); Close (shmid ); Return 0; } |
Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/POSIX $./shm_open
Size = 36, mode = 664
Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/POSIX $ LS-L/dev/SHM/XYZ
-RW-r -- 1 Simba 36 Jun 16 15:01/dev/SHM/XYZ
A 36-byte shared memory segment is created in the/dev/SHM directory.
Shm_write.c
C ++ code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
# Include <stdio. h> # Include <stdlib. h> # Include <sys/IPC. h> # Include <sys/types. h> # Include <unistd. h> # Include <errno. h> # Include <fcntl. h> # Include <sys/STAT. h> # Include <sys/Mman. h> # Include <string. h># Define err_exit (m )\ Do {\ Perror (m );\ Exit (exit_failure );\ } While (0) Typedef struct Stu { Char name [32]; Int age; } Stu; Int main (void) { Int shmid; Shmid = shm_open ("/XYZ", o_rdwr, 0 ); If (shmid =-1) Err_exit ("shm_open "); Struct stat Buf; If (fstat (shmid, & BUF) =-1) Err_exit ("fstat "); Printf ("size = % lD, mode = % O \ n", Buf. st_size, Buf. st_mode & 0777 ); Stu * P; P = (Stu *) MMAP (null, Buf. st_size, prot_write, map_shared, shmid, 0 ); If (P = map_failed) Err_exit ("MMAP "); Strcpy (p-> name, "test "); P-> age = 20; Close (shmid ); Return 0; } |
Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/POSIX $./shm_write
Size = 36, mode = 664
Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/POSIX $ OD-C/dev/SHM/XYZ
0000000 t e S t \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0
0000020 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0
0000040 024 \ 0 \ 0 \ 0
0000044
Use MMAP to map the shared memory to the process address space and pass the shmid into the FD parameter. There is no difference between the rest and the file ing. You can view the written content in OD-C.
Shm_read.c
C ++ code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
|
# Include <stdio. h> # Include <stdlib. h> # Include <sys/IPC. h> # Include <sys/types. h> # Include <unistd. h> # Include <errno. h> # Include <fcntl. h> # Include <sys/STAT. h> # Include <sys/Mman. h> # Include <string. h># Define err_exit (m )\ Do {\ Perror (m );\ Exit (exit_failure );\ } While (0) Typedef struct Stu { Char name [32]; Int age; } Stu; Int main (void) { Int shmid; Shmid = shm_open ("/XYZ", o_rdonly, 0 ); If (shmid =-1) Err_exit ("shm_open "); Struct stat Buf; If (fstat (shmid, & BUF) =-1) Err_exit ("fstat "); Printf ("size = % lD, mode = % O \ n", Buf. st_size, Buf. st_mode & 0777 ); Stu * P; P = (Stu *) MMAP (null, Buf. st_size, prot_read, map_shared, shmid, 0 ); If (P = map_failed) Err_exit ("MMAP "); Printf ("name = % s age = % d \ n", p-> name, p-> age ); Close (shmid ); Return 0; } |
Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/POSIX $./shm_read
Size = 36, mode = 664
Name = test age = 20
That is, the data in the shared memory is read. Note that the data in the shared memory still exists after the data is read, unless it is overwritten.
Reference: UNP