8

In Linux, I want to share some memory content of my process with other processes. one of the way to do this is using shm_open and mmap. like below.

/* Create a new memory object */
fd = shm_open( "/bolts", O_RDWR | O_CREAT, 0777 );
if( fd == -1 ) {
    fprintf( stderr, "Open failed:%s\n",
        strerror( errno ) );
    return EXIT_FAILURE;
}

/* Set the memory object's size */
if( ftruncate( fd, sizeof( *addr ) ) == -1 ) {
    fprintf( stderr, "ftruncate: %s\n",
        strerror( errno ) );
    return EXIT_FAILURE;
}

/* Map the memory object */
addr = mmap( 0, sizeof( *addr ),
        PROT_READ | PROT_WRITE,
        MAP_SHARED, fd, 0 );
if( addr == MAP_FAILED ) {
    fprintf( stderr, "mmap failed: %s\n",
        strerror( errno ) );
    return EXIT_FAILURE;
}

However, in this way, I can't share the "already allocated memory". my question is : can I share the previously allocated memory contents without re-allocating them?.

thank you in advance.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
daehee
  • 5,047
  • 7
  • 44
  • 70
  • It's quite hard to figure out what you mean by "already allocated memory" and "previously allocated memory". If you want to share that memory, just have another process open the /bolts path and mmap() it , the two processes will then share the same piece of memory. – nos Feb 18 '14 at 08:39
  • Read [shm_overview(7)](http://man7.org/linux/man-pages/man7/shm_overview.7.html) – Basile Starynkevitch Feb 18 '14 at 08:45
  • Step 1. suppose we have mmaped memory region at 0x1000 with RWX permission and MAP_PRITAVE|MAP_ANONYMOUS flag. Step 2. we write some data at memory address 0x1000. Step 3. we want to share the memory contents at 0x1000(virtual address must be 0x1000) with another process. I'm stuck at step 3. – daehee Feb 18 '14 at 10:00

1 Answers1

3

Your code does share the memory but both your processes will get different address regions. You want to have the same region, so addr value will be the same. In this case you can build objects in this memory, use internal pointers and your objects will be valid and visible in both processes.

There are two methods how you can do that.

1) do fork() to create another process

2) ask mmap to allocate memory at the special address with MAP_FIXED.

For number two your code will looks:

/* Create a new memory object */
fd = shm_open( "/bolts", O_RDWR | O_CREAT, 0777 );
if( fd == -1 ) {
    fprintf( stderr, "Open failed:%s\n",
        strerror( errno ) );
    return EXIT_FAILURE;
}

/* Set the memory object's size */
if( ftruncate( fd, sizeof( *addr ) ) == -1 ) {
    fprintf( stderr, "ftruncate: %s\n",
        strerror( errno ) );
    return EXIT_FAILURE;
}

// You base address for memory region that you want to share. 
// Choose this carefully, you both processes MUST have it available!
void * baseAddr = 0x7fff00000000; 

/* Map the memory object */
addr = mmap( baseAddr, sizeof( *addr ),
        PROT_READ | PROT_WRITE,
        MAP_SHARED | MAP_FIXED, fd, 0 );

if( addr == MAP_FAILED | MAP_FIXED ) {
    fprintf( stderr, "mmap failed: %s\n",
        strerror( errno ) );
    return EXIT_FAILURE;
}

image

BayK
  • 118
  • 7
  • According to the manpage for both Posix and Linux, MAP_FIXED will replace any existing memory at the location with new memory---I.e., it will not share existing memory. – Daniel Oct 07 '22 at 22:24