Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I share existing memory with shm_open?

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.

like image 524
daehee Avatar asked Feb 18 '14 08:02

daehee


1 Answers

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

like image 95
BayK Avatar answered Oct 02 '22 06:10

BayK