Playing with shared memory - problem with non 'simple' data types

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: Feb 2005
Posts: 466
Reputation: winbatch is on a distinguished road 
Solved Threads: 18
winbatch's Avatar
winbatch winbatch is offline Offline
Posting Pro in Training

Playing with shared memory - problem with non 'simple' data types

 
0
  #1
May 24th, 2005
Hi,

In my never ending quest to improve my C++, I'm trying to write a class that sets and reads shared memory. For the time being I am avoiding dealing with issues of concurrency/locking, etc. and starting small. I was successfully able to put into shared memory things like integers, char *, and even my own custom classes. (By making it a templated class).

However, I seem to be running into a problem if I attempt to use either a datatype or a class that contains a member that is of a datatype 'non native', ie like a 'string', or 'vector', I either crash or get garbage. I'm coming to the conclusion that I simply can't store these datatypes, given that the shared memory is 'C' code rather than C++. Could you confirm my assumption that it basically can't handle C++ types, or is it something in my code that would cause this problem?

Below is my SharedMemory class. (Note that all code is in the .h file right now - I'll separate it out when I use it more officially).
  1. extern "C"
  2. {
  3. #include <sys/types.h>
  4. #include <sys/ipc.h>
  5. #include <sys/shm.h>
  6. }
  7. template <class InputClass>
  8. class SharedMemory
  9. {
  10. private:
  11. key_t key;
  12. int shmid;
  13. InputClass *data;
  14. int SHM_SIZE;
  15. string fileName;
  16.  
  17. void initialize()
  18. {
  19. if ((key = ftok(fileName.c_str(), 'R')) == -1)
  20. {
  21. throw DHException( "*** Could not connect to shared memory file [" + fileName + "] Check that the file exists...***" );
  22. }
  23.  
  24. /* connect to (and possibly create) the segment: */
  25. if ((shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1)
  26. {
  27. throw DHException( "*** Could not use shared memory file: [" + fileName + "] Check that the allocated size is OK..***");
  28. }
  29.  
  30. data = (InputClass *) shmat(shmid, 0, 0);
  31. if (data == (InputClass *)(-1))
  32. {
  33. throw DHException ( "*** Could not connect to shared memory file:(error 3):" + fileName);
  34. }
  35. }
  36.  
  37. public:
  38. SharedMemory( string file )
  39. {
  40. SHM_SIZE=sizeof(InputClass);
  41. fileName = file;
  42. initialize();
  43.  
  44. }
  45.  
  46. SharedMemory( int size, string file )
  47. {
  48. SHM_SIZE=size;
  49. fileName = file;
  50. initialize();
  51. }
  52.  
  53.  
  54. void writeToSharedMemory( InputClass ic )
  55. {
  56. *data = ic;
  57. }
  58.  
  59. InputClass getFromSharedMemory( )
  60. {
  61. return *data;
  62. }
  63.  
  64. ~SharedMemory()
  65. {
  66.  
  67. if (shmdt((char *)data) == -1)
  68. {
  69. throw DHException ( "Could not disconnect from shared memory file:" + fileName );
  70. }
  71. }
  72.  
  73. int getMemorySize() { return SHM_SIZE; }

An example of usage would be (where Date is a custom class of mine that only contains native types like int's, time_t, etc.):

  1. SharedMemory<Date> shm(1000, "DANTEST" );
  2.  
  3. while ( true )
  4. {
  5.  
  6. Date a;
  7. shm.writeToSharedMemory(a);
  8. screenLog<<"Just Placed:"<<a<<endl;
  9.  
  10. sleep( 1 );
  11.  
  12. }
Reply With Quote Quick reply to this message  
Join Date: Apr 2004
Posts: 4,342
Reputation: Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future 
Solved Threads: 237
Team Colleague
Dave Sinkula's Avatar
Dave Sinkula Dave Sinkula is offline Offline
long time no c

Re: Playing with shared memory - problem with non 'simple' data types

 
0
  #2
May 25th, 2005
I'm not familiar with the libraries you are working with, but perhaps the "'non native', ie like a 'string', or 'vector'" issue is because they are not POD types?
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Reply With Quote Quick reply to this message  
Join Date: Feb 2005
Posts: 466
Reputation: winbatch is on a distinguished road 
Solved Threads: 18
winbatch's Avatar
winbatch winbatch is offline Offline
Posting Pro in Training

Re: Playing with shared memory - problem with non 'simple' data types

 
0
  #3
May 25th, 2005
I think my made up definition of 'non native' is the same as your 'non POD'. With that having been said, are they not useable with shared memory?
Reply With Quote Quick reply to this message  
Join Date: Apr 2004
Posts: 4,342
Reputation: Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future 
Solved Threads: 237
Team Colleague
Dave Sinkula's Avatar
Dave Sinkula Dave Sinkula is offline Offline
long time no c

Re: Playing with shared memory - problem with non 'simple' data types

 
0
  #4
May 25th, 2005
Well I think I had plain old data confused with "things that need a deep copy; things for which a shallow copy would not suffice" -- that is, things that have dynamically-allocated memory rather than a simple array. Something like that.
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Reply With Quote Quick reply to this message  
Join Date: Feb 2005
Posts: 466
Reputation: winbatch is on a distinguished road 
Solved Threads: 18
winbatch's Avatar
winbatch winbatch is offline Offline
Posting Pro in Training

Re: Playing with shared memory - problem with non 'simple' data types

 
0
  #5
May 25th, 2005
Unfortunately, that went over my head. (Was that a no, you can't use dynamically allocated datatypes, or yes, you can)
Reply With Quote Quick reply to this message  
Join Date: Apr 2004
Posts: 4,342
Reputation: Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future 
Solved Threads: 237
Team Colleague
Dave Sinkula's Avatar
Dave Sinkula Dave Sinkula is offline Offline
long time no c

Re: Playing with shared memory - problem with non 'simple' data types

 
0
  #6
May 25th, 2005
First, I looked up a better description of POD. (This seems to say "yup" to your previous post.)
Originally Posted by winbatch
Unfortunately, that went over my head. (Was that a no, you can't use dynamically allocated datatypes, or yes, you can)
And I found a better description of deep copy. But essentially, I believe I was saying no. I'll qualify that with: perhaps you may, but you'd need to make a deep copy.[?]
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Reply With Quote Quick reply to this message  
Join Date: Feb 2005
Posts: 466
Reputation: winbatch is on a distinguished road 
Solved Threads: 18
winbatch's Avatar
winbatch winbatch is offline Offline
Posting Pro in Training

Re: Playing with shared memory - problem with non 'simple' data types

 
0
  #7
May 26th, 2005
That's interesting because I found that if I was reading and writing from the shared memory inside the same program it worked, but when trying to read those special parts (string, vector) from another program, that's when it failed. Could be because of the shallow/deep copy. I guess I'll have to look into how to deal with that. (Though if I'm simply using the std::string, I don't think it should be me who creates a proper copy constructor for it?)
Reply With Quote Quick reply to this message  
Join Date: Apr 2004
Posts: 4,342
Reputation: Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future 
Solved Threads: 237
Team Colleague
Dave Sinkula's Avatar
Dave Sinkula Dave Sinkula is offline Offline
long time no c

Re: Playing with shared memory - problem with non 'simple' data types

 
0
  #8
May 26th, 2005
Originally Posted by winbatch
That's interesting because I found that if I was reading and writing from the shared memory inside the same program it worked, but when trying to read those special parts (string, vector) from another program, that's when it failed.
I'm venturing forth into the unknown a bit here, but I'll offer a guess. Here is some code that probably does things it shouldn't, but I'm using it as a prop for my guesses. (Doesn't that make it sound great.) :rolleyes:
#include <iostream>
#include <string>
#include <cstddef>

void showobject(const void *object, std::size_t size)
{
   const unsigned char *byte = static_cast<const unsigned char *>(object);
   for (size_t i = 0; i < size; ++i)
   {
      std::cout << std::hex << static_cast<int>(byte[i]);
   }
   std::cout << std::endl;
}

int main()
{
   std::string text("hello world");
   std::cout << text << " : ";
   showobject(static_cast<const void *>(&text), sizeof text);
   std::cout << text.c_str() << " : ";
   showobject(static_cast<const void *>(text.c_str()), text.size());
   std::cout << static_cast<const void *>(&text[0]) << std::endl;
   return 0;
}

/* my output
hello world : 4454201000143b7b01000
hello world : 68656c6c6f20776f726c64
007B3B14
007B3B14
*/
You can kinda see that something in the string points to the memory that contains the actual string text.

Let's say that Program A and Program B share a string using shared memory. That means each shares the whole first line (of the output displayed). But Program A's memory is different from Program B's, so Program A points to a "hello world", but Program B's memory at 007B3B14 is different.

Anybody feel free to bail me out if I'm completely off target here.
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Reply With Quote Quick reply to this message  
Join Date: May 2005
Posts: 232
Reputation: Dogtree is an unknown quantity at this point 
Solved Threads: 3
Dogtree's Avatar
Dogtree Dogtree is offline Offline
Posting Whiz in Training

Re: Playing with shared memory - problem with non 'simple' data types

 
0
  #9
May 31st, 2005
The diagnosis is accurate for the most part. Shared memory can't handle non-POD types. You could write a special purpose allocator for your standard containers, and unshared proxy objects that refer to a reasonable representation of the data in shared memory for everything else. I don't have a lot of experience with shared memory, so I won't try to give you code because it would be hopelessly broken. But this is a good problem to solve with threads rather than IPC and processes.

I imagine that the proxy solution would be the easiest for you. You can serialize the data into, say, a C-style string representation for storage in shared memory, and the proxy class would be able to represent it as whatever object you need when you need it for a minor conversion cost. Here's a crude example for std::string:
  1. class string_proxy {
  2. std::string _str;
  3. char *_mem;
  4. public:
  5. std::string_proxy(char *addr): _mem(addr) {}
  6. std::string& get() { _str.assign(_mem); }
  7. void serialize()
  8. {
  9. memcpy(_mem, _str.c_str(), _str.size() + 1);
  10. }
  11. };
With std::string and other standard containers you can write a custom allocator that knows about the shared memory and doesn't make your system cry when you use it. But that's harder, and depends heavily on knowing what you're doing with the shared memory library, which I don't, so I won't show you code.
Reply With Quote Quick reply to this message  
Join Date: Feb 2005
Posts: 466
Reputation: winbatch is on a distinguished road 
Solved Threads: 18
winbatch's Avatar
winbatch winbatch is offline Offline
Posting Pro in Training

Re: Playing with shared memory - problem with non 'simple' data types

 
0
  #10
May 31st, 2005
To make sure I understand, basically you write a function that takes your class contents, makes in effect a big string out of it. It's that string I put in shared memory. You then have a function that can take the big string and turn it back into the class contents again. I can then read the big string from shared memory and then reform the class.

If I've got you right, as long as I make my shared memory segment large enough to handle the size the string version I should be ok. Is that right?
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Other Threads in the C++ Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC