c++ - Named Shared Memory: shm_open not providing the correct location -


i having difficulty using shared memory. believe misunderstanding how shared memory supposed work. trying create template class project wrap posix shared memory api. when call mmap() second time, in same process, expecting see same ptr returned first time. not seeing. second address offset 0x1000 (i assume page boundary). when write first memory mapped location, data not show in second.

i thought possibly data not getting syncd, tried calling msync(). did not help.

i suspect of different addresses returned mmap(). seems might pointer-pointer, no of documentation or examples show pointer-pointers. so...

obviously, leads me believe either doing wrong or misunderstand how named shared memory supposed work within same process.

i have been pouring on man pages , on looking answers no avail.

could please tell me doing wrong access same named shared memory location? or point me answer provides explanation require me on way again.

please excuse debug cout , excessive documentation, trying understand/learn shared_memory api.

note: i understand there better ways share data within same process. but, short test driver , template used in multi-process environment.

edit: im not sure matters, trying run on suse linux 3.0.101



"help me obi-wan kenobi, you're hope!"

shmem.h

// **************************************************************************** // posix shared memory //     document richard stevens  //     "unix network programming: interprocess communications" vol 2, 2nd ed. // ------------------- // // shared memory fastest form of ipc available, because 1 copy of // data in shared memory available threads or processes // share memory. form of synchronization required, // however, coordinate threads or processes sharing memory. // // posix provides 2 ways share memory between unrelated processes. //      1. memory-mapped files: file opened open, , resulting //         descriptor mapped address space of process mmap. //         memory-mapped files can shared between unrelated processes. //      2. shared memory objects: function shm_open opens posix ipc name //         (perhaps pathname in filesystem), returning descriptor //         mapped address space of process mmap. // // both techniques require call mmap. differs how descriptor // argument mmap obtained: open or shm_open. // // **************************************************************************** #ifndef shmem_h_ #define shmem_h_  #include <errno.h>      // error checking #include <fcntl.h>      // o_ constants #include <semaphore.h>  // semaphore api #include <stddef.h>     // defines null #include <sys/mman.h>   // shared memory api #include <sys/stat.h>   // mode constants #include <unistd.h>     // close()  #include <iostream> using namespace std;  template <class t, long count = 1> class shmem { public:      // ------------------------------------------------------------------------     shmem(const char* name) :         pname(name), pshmdata(0), mshmfd(0), mcreated(true)     {         cout << "start: shmem(\"" << pname << "\", " << count << ") constructor" << endl<< flush;          // --------------------------------------------------------------------         // two-step process involved posix shared memory requires:         //      1. calling shm_open, specifying name argument, either         //         create new shared memory object or open existing         //         shared memory object, followed         //      2. calling mmap map shared memory address space         //         of calling process.         int    flags = o_rdwr|o_creat|o_excl;         mode_t mode  = s_irusr|s_iwusr;          // flag indicating shared memory same data         // passed in         bool valid = true;          // determine amount of memory should include         // header + data buffer         const size_t len = sizeof(shmem_data_t);          cout << "shmem_open()... "<< flush;         mshmfd = shm_open(pname, flags, mode);          // check see if shared memory has been created yet         if (mshmfd == -1)         {             cout << "failed. ********************* errno: " << errno << endl<< flush;              // remove flags (o_excl, o_creat) , try open shared memory             // exists             flags &= ~o_excl;             flags &= ~o_creat;              cout << "shmem_open (again)... "<< flush;             mshmfd = shm_open(pname, flags, mode);              // check see if error occurred while trying open             valid = (mshmfd != -1);              if (valid)                         {                 cout << "success!" << endl<< flush;                              // indicate shared memory existed                             mcreated = false;                         }             else                         {                 cout << "failed. ********************* errno: " << errno << endl<< flush;                         }          } else         {             cout << "success!" << endl << flush;         }          cout << "mmap()... "<< flush;         // mmap function maps posix shared memory object (t) + header         // address space of process.         pshmdata = reinterpret_cast<shmem_data_t*> (                 mmap(null, len, prot_read|prot_write, map_shared|map_anonymous, mshmfd, 0));          if (pshmdata == null)         {             int error = errno;              switch (error)             {             default:                 // undefined error                 cout << "failed: ********************* errno: " << error << endl<< flush;                 break;             }         } else         {             cout << "success: " << hex << "0x" << pshmdata << dec << endl << flush;         }          // check see if first user request shared memory         // location.         if (mcreated)         {             cout << "created!" << endl;             cout << "initial header data: size  " << pshmdata->size  << endl;             cout << "initial header data: count " << pshmdata->len << endl;              // initialize header if created shm             cout << "sem_init()" << endl<< flush;             sem_init(&pshmdata->mutex,1,1);              cout << "sem_wait()... " << endl<< flush;             sem_wait(&pshmdata->mutex);              cout << "got it!" << endl<< flush;             pshmdata->size  = len;             pshmdata->len = count;              cout << "release semaphore" << endl<< flush;             sem_post(&pshmdata->mutex);             cout << "initialization complete" << endl<< flush;              cout << "header data: size  " << pshmdata->size  << endl;             cout << "header data: count " << pshmdata->len << endl;          } else if (valid)         {              cout << "validating shared memory... " ;              // validate shared memory acquired             valid &= (pshmdata->size == len);             valid &= (pshmdata->len == count);              if (valid)                 cout << "success!" << endl<< flush;             else                 cout << "failed. ********************* " << endl<< flush;              cout << "header data: size  " << pshmdata->size  << endl;             cout << "header data: count " << pshmdata->len << endl;           } else { shm_unlink(pname); exit(1); }                  // fixme: should if aren't valid?!         cout << "end: shmem constructor" << endl<< flush;      }      // ------------------------------------------------------------------------     // copy constructor - increment use count shared memory.     shmem(const shmem& that) :         pname(that.pname), pshmdata(0), mshmfd(0)     {         cout << "start: shmem copy constructor" << endl << flush;          // --------------------------------------------------------------------         // two-step process involved posix shared memory requires:         //      1. calling shm_open, specifying name argument, either         //         create new shared memory object or open existing         //         shared memory object, followed         //      2. calling mmap map shared memory address space         //         of calling process.         int    flags = o_rdwr;         mode_t mode  = s_irusr|s_iwusr;          // flag indicating allocated valid shared memory         // same data passed in         bool valid = true;          // determine amount of memory should include         // header + data buffer         const size_t len = sizeof(shmem_data_t);          mshmfd = shm_open(pname, flags, mode);          // check see if error occurred while trying open         valid = (mshmfd != -1);          // mmap function maps posix shared memory object (t) + header         // address space of process.         pshmdata = mmap(null, that.mshmfd->size, prot_read|prot_write, map_shared|map_anonymous, mshmfd, 0);          cout << "close()... "<< flush;         // close() function deallocate file descriptor.         // outstanding record locks owned process on file         // associated file descriptor removed (that is,         // unlocked).         //         // if shared memory object remains referenced @ last close (that is,         // process has mapped), entire contents of memory object persist         // until memory object becomes unreferenced. if last close of         // memory object , close results in memory object becoming         // unreferenced, , memory object has been unlinked, memory object         // removed.         close(mshmfd);         cout << "success." << endl<< flush;           cout << "end: shmem copy constructor" << endl << flush;      }       // ------------------------------------------------------------------------     virtual ~shmem()     {          cout << "start: ~shmem() destructor" << endl<< flush;                  if (mcreated)                 {         cout << "shm_unlink( \"" << pname << "\")... "<< flush;          // shm_unlink function removes name of shared memory object.         // other unlink functions, unlinking name has no         // effect on existing references underlying object, until         // references object closed. unlinking name prevents         // subsequent call open, mq_open, or sem_open succeeding.         if(shm_unlink(pname) == -1)         {             int error = errno;              switch (error)             {             case eacces:                 // permission denied unlink named shared memory                 // object.                 cout << "failed: ********************* eacces " << endl<< flush;                 break;              case enametoolong:                 // length of name argument exceeds {path_max} or                 // pathname component longer {name_max}.                 cout << "failed: ********************* enametoolong" << endl<< flush;                 break;              case enoent:                 // named shared memory object not exist.                 cout << "failed: ********************* enoent" << endl<< flush;                 break;              default:                 // undefined error                 cout << "failed: ********************* <unknown> errno: " << error << endl<< flush;                 break;             }         } else         {             cout << "success!" << endl<< flush;         }                  }          cout << "close()... " << flush;         // close() function deallocate file descriptor.         // outstanding record locks owned process on file         // associated file descriptor removed (that is,         // unlocked).         //         // if shared memory object remains referenced @ last close (that is,         // process has mapped), entire contents of memory object persist         // until memory object becomes unreferenced. if last close of         // memory object , close results in memory object becoming         // unreferenced, , memory object has been unlinked, memory object         // removed.         close(mshmfd);         cout << "success." << endl << flush;            cout << "end: ~shmem() destructor" << endl<< flush;     }       // ------------------------------------------------------------------------     // returns address indexed object in shared memory     t* obj_addr(uint32_t n = 0)     {         cout << "shmem.obj_addr()" << endl << flush;         return &pshmdata->buf[n];     }      // ------------------------------------------------------------------------     // sync...     void sync()     {                 cout << "shmem.sync()... ";                if (msync(pshmdata, sizeof(shmem_data_t), ms_sync) == -1)                {                    cout << "failed: ********************* errno: " << errno << endl<< flush;                } else                {                    cout << "success. " << endl << flush;                }             }      // ------------------------------------------------------------------------     // returns reference indexed object in shared memory     t& obj(uint32_t n = 0)     {         cout << "shmem.obj()" << endl << flush;         return pshmdata->buf[n];     }      // ------------------------------------------------------------------------     // returns reference indexed object in shared memory     t& operator[] (uint32_t n)     {         cout << "accessing shmem[" << n << "] == " << flush;         cout << pshmdata->buf[n] << "!"  << endl << flush;         return pshmdata->buf[n];     }   private:     // ------------------------------------------------------------------------     // hide default constructor     shmem() : pname(0), pshmdata(0), mshmfd(0)     {      }  private:     struct shmem_data_t     {         size_t   size;         uint32_t len;         sem_t    mutex;         t        buf[count];     };      const char*   pname;     shmem_data_t* pshmdata;     int           mshmfd;         // flag indicating created shared memory bool mcreated;   };  #endif /* shmem_h_ */ 

main.cpp

#include <signal.h> #include <stdlib.h> #include <string.h>  #include <iostream> // ** fixme ** debug using namespace std;  #include "stdint.h" #include "shmem.h"  bool done = false;  // ---------------------------------------------------------------------------- void my_handler(int s) {           cout << "goodbye! sig: " << s << endl << flush;           done = true; }  // ---------------------------------------------------------------------------- void test_shmem() {      cout << endl << endl << "testing shmem template" << endl;     cout << "-------------------------------------------" << endl;     shmem<int,13> x("/jco");     cout << "-------------------------------------------" << endl;     shmem<int,13> y("/jco");     cout << "-------------------------------------------" << endl;     x[5] = 7;         x.sync();     cout << "-------------------------------------------" << endl;     cout << "x[5] = " << x[5] << endl;     cout << "-------------------------------------------" << endl;     cout << "y[5] = " << y[5] << endl;     cout << "-------------------------------------------" << endl;     cout << endl << "*** testing complete." << endl << endl;      sleep(10);  }  // ---------------------------------------------------------------------------- int main() {     cout << "main" << endl;     struct sigaction siginthandler;     siginthandler.sa_handler = my_handler;    sigemptyset(&siginthandler.sa_mask);    siginthandler.sa_flags = 0;     sigaction(sigint, &siginthandler, null);       test_shmem();      // run     while(not done)     {         sleep(1);     }      return 0; } 

console output:

main   testing shmem template ------------------------------------------- start: shmem("/jco", 13) constructor shmem_open()... success! mmap()... success: 0x0x7f32113ad000 created! initial header data: size  0 initial header data: count 0 sem_init() sem_wait()... got it! release semaphore initialization complete header data: size  104 header data: count 13 end: shmem constructor ------------------------------------------- start: shmem("/jco", 13) constructor shmem_open()... failed. ********************* errno: 17 shmem_open (again)... success! mmap()... success: 0x0x7f32113ac000 validating shared memory... failed. ********************* header data: size  0 header data: count 0 end: shmem constructor ------------------------------------------- accessing shmem[5] == 0! shmem.sync()... success. ------------------------------------------- accessing shmem[5] == 7! x[5] = 7 ------------------------------------------- accessing shmem[5] == 0! y[5] = 0 -------------------------------------------  *** testing complete.  start: ~shmem() destructor close()... success. end: ~shmem() destructor start: ~shmem() destructor shm_unlink( "/jco")... success! close()... success. end: ~shmem() destructor goodbye! sig: 2 

edit: first answer missed mark. feel obligated contribute useful.

both petesh , bЈовић gave correct answers. first, should not using map_anonymous. second, should realize (virtual) address mmap not same first one. when call mmap twice, creating 2 separate mappings same shared memory. can use either of 2 addresses , pointing @ same piece of shared memory.

i wrote small program demonstrate. program does, , shows though 2 mmap calls return 2 different addresses, both addresses reading , writing same shared memory.

#include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <unistd.h>  #define temp_filename   "shm.tmp"  int main(void) {     int fd1 = shm_open(temp_filename, o_creat | o_rdwr, 0777);     int fd2 = shm_open(temp_filename, o_rdwr, 0777);     int *p1, *p2;     int buf[1024] = {0x12345678};      // write initial contents shared memory.     write(fd1, buf, 4096);     p1 = mmap(null, 4096, prot_read|prot_write, map_shared, fd1, 0);     p2 = mmap(null, 4096, prot_read|prot_write, map_shared, fd2, 0);     printf("fd1 = %d, p1 = %p\n", fd1, p1);     printf("fd2 = %d, p2 = %p\n", fd2, p2);     printf("p1[0] = 0x%08x, p2[0] = 0x%08x\n", p1[0], p2[0]);     p1[0] = 0xdeadbeef;     printf("p1[0] = 0x%08x, p2[0] = 0x%08x\n", p1[0], p2[0]);     close(fd2);     close(fd1);     shm_unlink(temp_filename);     return 0; } 

and output:

fd1 = 3, p1 = 0x7f2b3d434000 fd2 = 4, p2 = 0x7f2b3d433000 p1[0] = 0x12345678, p2[0] = 0x12345678 p1[0] = 0xdeadbeef, p2[0] = 0xdeadbeef 

Comments

Popular posts from this blog

python - mat is not a numerical tuple : openCV error -

c# - MSAA finds controls UI Automation doesn't -

wordpress - .htaccess: RewriteRule: bad flag delimiters -