944,198 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Unsolved
  • Views: 5324
  • C++ RSS
You are currently viewing page 1 of this multi-page discussion thread
May 24th, 2005
0

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

Expand Post »
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).
C++ Syntax (Toggle Plain Text)
  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.):

C++ Syntax (Toggle Plain Text)
  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. }
Reputation Points: 68
Solved Threads: 18
Posting Pro in Training
winbatch is offline Offline
466 posts
since Feb 2005
May 25th, 2005
0

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

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?
Team Colleague
Reputation Points: 2780
Solved Threads: 312
long time no c
Dave Sinkula is offline Offline
4,790 posts
since Apr 2004
May 25th, 2005
0

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

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?
Reputation Points: 68
Solved Threads: 18
Posting Pro in Training
winbatch is offline Offline
466 posts
since Feb 2005
May 25th, 2005
0

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

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.
Team Colleague
Reputation Points: 2780
Solved Threads: 312
long time no c
Dave Sinkula is offline Offline
4,790 posts
since Apr 2004
May 25th, 2005
0

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

Unfortunately, that went over my head. (Was that a no, you can't use dynamically allocated datatypes, or yes, you can)
Reputation Points: 68
Solved Threads: 18
Posting Pro in Training
winbatch is offline Offline
466 posts
since Feb 2005
May 25th, 2005
0

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

First, I looked up a better description of POD. (This seems to say "yup" to your previous post.)
Quote 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.[?]
Team Colleague
Reputation Points: 2780
Solved Threads: 312
long time no c
Dave Sinkula is offline Offline
4,790 posts
since Apr 2004
May 26th, 2005
0

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

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?)
Reputation Points: 68
Solved Threads: 18
Posting Pro in Training
winbatch is offline Offline
466 posts
since Feb 2005
May 26th, 2005
0

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

Quote 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.
Team Colleague
Reputation Points: 2780
Solved Threads: 312
long time no c
Dave Sinkula is offline Offline
4,790 posts
since Apr 2004
May 31st, 2005
0

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

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:
C++ Syntax (Toggle Plain Text)
  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.
Reputation Points: 35
Solved Threads: 3
Posting Whiz in Training
Dogtree is offline Offline
232 posts
since May 2005
May 31st, 2005
0

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

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?
Reputation Points: 68
Solved Threads: 18
Posting Pro in Training
winbatch is offline Offline
466 posts
since Feb 2005

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: 2038 Problem
Next Thread in C++ Forum Timeline: Help me to delete a file





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC