Skip to content

Instantly share code, notes, and snippets.

@drmalex07
Created March 17, 2017 09:47
Show Gist options
  • Save drmalex07/5b72ecb243ea1f5b4fec37a6073d9d23 to your computer and use it in GitHub Desktop.
Save drmalex07/5b72ecb243ea1f5b4fec37a6073d9d23 to your computer and use it in GitHub Desktop.
An example of using shared memory in a POSIX system. #c #linux #shmem #shm_open #shared-memory
// Note: Link with -lrt
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include <unistd.h>
#include <string.h>
#include <assert.h>
int main(int argc, char **argv) {
int oflags=O_RDWR;
int opt;
while ((opt = getopt(argc, argv, "c")) != -1) {
switch (opt) {
case 'c': /* create it */
oflags = O_RDWR | O_CREAT;
break;
default: /* '?' */
fprintf(stderr, "Usage: %s -[c]\n", argv[0]);
exit(EXIT_FAILURE);
}
}
off_t length = 2 * 1024;
char *name = "/malex.hello03.01";
int fd = shm_open(name, oflags, 0644 );
ftruncate(fd, length);
fprintf(stderr,"Shared Mem Descriptor: fd=%d\n", fd);
assert (fd>0);
u_char *ptr = (u_char *) mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
fprintf(stderr, "Shared Memory Address: %p [0..%lu]\n", ptr, length-1);
fprintf(stderr, "Shared Memory Path: /dev/shm/%s\n", name );
assert (ptr);
char *msg = "hello world!!\n";
strcpy((char*)ptr,msg);
close(fd);
exit(0);
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include <unistd.h>
#include <string.h>
#include <assert.h>
int main(int argc, char **argv) {
int oflags=O_RDWR;
int i;
char *name = "/malex.hello03.01";
int fd = shm_open(name, oflags, 0644 );
fprintf(stderr,"Shared Mem Descriptor: fd=%d\n", fd);
assert (fd>0);
struct stat sb;
fstat(fd, &sb);
off_t length = sb.st_size ;
u_char *ptr = (u_char *) mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
fprintf(stderr, "Shared Mem Address: %p [0..%lu]\n", ptr, length-1);
assert (ptr);
// hexdump first 100 bytes
fprintf(stdout,"First 100 bytes:\n");
for(i=0; i<100; i++)
fprintf(stdout, "%02X%s", ptr[i], (i%25==24)?("\n"):(" ") );
// change 1st byte
ptr[ 0 ] = 'H' ;
close(fd);
exit(0);
}
@pharapeti
Copy link

What does 0644 mean in shm_open(name, oflags, 0644 );?

@drmalex07
Copy link
Author

@pharapeti
it is the ownership mode, just like in the open system call

@DharminB
Copy link

DharminB commented Feb 5, 2021

Thank you for this example. It was really helpful.
However, I have a question. Any particular reason for not using shm_unlink or munmap? Is it not necessary?

@drmalex07
Copy link
Author

@DharminB
shm_unlink would delete the shared memory region from the OS (it appears under /dev/shm); in many cases we want it to remain for other processes to read/write to it.
munmap would destroy (invalidate) the memory mapping for the pointer pointing to the shm region. This affects only the current process and it automatically happens when the process terminates.

@samuel100u
Copy link

samuel100u commented Mar 9, 2022

@drmalex07

shm_unlink would delete the file under /dev/shm/xxxxx even there are other processes using it ?

@drmalex07
Copy link
Author

@samuel100u
no, it uses a reference-count approach: the OS will delete the region only when all processes have been unlinked. See also the man page

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment