[interprocess] another newbie question: clean-up
Hi,
after I go really quick help here from Ion, I've another question.
I managed it to implement a map
Hi, Wolfgang Hottgenroth wrote:
Hi, [snip]
To put pair into the map I wrote:
typedef boost::interprocess::allocator
ShmemStringAllocator; typedef boost::interprocess::basic_string MyString; MyString key(segment.get_segment_manager()); MyString value(segment.get_segment_manager());
key = "key1"; value = "value1";
mymap->insert(std::pair
(key, value)); (For the complete code see http://www.hottis.de/boost/strings/. Thanks.)
What I'm wondering is: will the memory required for key and value be freed automatically in the writing process (put.C)?
If you refer to the local "key" and "value" variables, the string objects (the class that contains a pointer to a dynamically allocated object) are allocated in your process' stack, but the dynamically allocated buffers holding "key1" and "value1" are allocated in shared memory. When "key" and "value" go out of scope, memory is automatically reclaimed. Just like std::string. The difference is that std::string allocates the internal buffer calling std::allocator::allocate (that is, operator new[]), whereas boost::interprocess::allocator will allocate the string from shared memory (using boost::interprocess::allocator::allocate). But anyway, when the object is destroyed, memory is freed.
When I like to erase an element from the map, do I need to do more than just calling mymap->erase(key)?
No. That's all. All the dynamic memory from the strings (allocated in the shared memory segment) is also freed.
And finally when I'm done and like to remove the whole map, is more required than segment.destroy<MyMap>("MyMap")? Will all the MyString's in the map go too?
Yes. All will be automatically freed.
Furthermore: is it possible to use a map in shared memory as an associative array and write:
MyString value = (*mymap)[key];
It doesn't compile for me.
The problem when using operator[], is that the mapped type must be default constructible. And boost::interprocess::basic_string, needs the allocator argument. You will need to use insert, sorry.
Thanks, Wolfgang
Regards, Ion
Hi,
first of all: many thanks to Ion, it was very helpful.
But here is my next problem: Can I and how can I increase the size of a
shared memory segment?
I've my map
Wolfgang Hottgenroth wrote:
Hi,
first of all: many thanks to Ion, it was very helpful.
But here is my next problem: Can I and how can I increase the size of a shared memory segment?
You can't do that with current Interprocess functions. Maybe I should add that as a new to-do. There are two difficulties: -> Should we maintain the base address? -> What if extending fails? Should I preserve the old shared memory? -> Should the expansion be atomic? (And this maybe can't be achieved, because another process can be doing something in the segment and we have no locks to stop it) I will think about it when I have a bit of time. But I'm afraid it will take some time. If you know the objects your shared memory contains, you can create a new managed_shared_memory and create a new map taking the old map as an argument. Something like: managed_shared_memory new_shm(...); new_shm.construct<MyMap>("name")(old_map); This would reproduce the old map in the new map. On the other hand, you will need to notify other processes about this. Shared memory is fixed size and I'm afraid we can't do much to improve this... I've tried to experiment a bit with multi-segment shared memory (mapping more shared memory when needed) but the problem is that somehow other processes must be notified atomically. And I have no solution for this. So I'm afraid I have no solution for a dynamically growable shared memory ;-( Regards, Ion
participants (2)
-
Ion Gaztañaga
-
Wolfgang Hottgenroth