0

I am new to boost. I am using “boost managed shared memory” in the following sample but one instance gets crashed while allocating memory in the shared segment on the following line :

char_string  key_object(keyHashStr.c_str(), alloc_inst3);

The crash occurs only if more than one instance of my sample application are running at the same time. If I use “boost managed windows shared memory” then there is no crash.

Can someone please let me know what I am doing wrong ?

    #include <boost/interprocess/sync/interprocess_mutex.hpp>
    #include <boost/interprocess/sync/scoped_lock.hpp>
    #include <boost/interprocess/managed_shared_memory.hpp>
    #include <boost/interprocess/shared_memory_object.hpp>
    #include <boost/interprocess/allocators/allocator.hpp>
    #include <boost/interprocess/containers/flat_map.hpp>
    #include <boost/interprocess/containers/set.hpp>
    #include <boost/interprocess/containers/string.hpp>
    #include <string>
    #include <Windows.h>
    #include <iostream>

    #define AMMSRCUNITLIMIT 0x0100000 /* 1M bytes */
    #define RESERVED_BUFFER_SIZE_WRITE (8 * AMMSRCUNITLIMIT)
    #define SHM_SIZE_FOR_TRACKING 65536
    #define MAX_PATH 260

    using namespace boost::interprocess;

    //Typedefs of allocators and containers
    typedef allocator<void, managed_shared_memory::segment_manager>      void_allocator;
    typedef allocator<char, managed_shared_memory::segment_manager>      char_allocator;
    typedef boost::interprocess::basic_string<char, std::char_traits<char>, char_allocator>   char_string;

    int main(int argc, char *argv[])
    {
           managed_shared_memory *m_sharedMemUsage = NULL;
           string keyHashStr;

           try
           {
                  m_sharedMemUsage = new  managed_shared_memory(create_only, "MyBookkeeper", 2 * RESERVED_BUFFER_SIZE_WRITE);
                  keyHashStr = "AAAAAAAAAAAAAAAAAAAAAAA";
           }
           catch (...)
           {
                  while (true)
                  {
                         try{
                               m_sharedMemUsage = new managed_shared_memory(open_only, "MyBookkeeper");
                               break;
                         }
                         catch (...)
                         {
                               std::cout << "Some problem, trying again" << std::endl;
                         }
                  }
                  keyHashStr = "AAAAAAAAAAAAAAAAAAAAAAB";
           }

           {
                  char_allocator alloc_inst3 = m_sharedMemUsage->get_segment_manager()->get_allocator<char>();
                  int count = 0;
                  while (count < 100000)
                  {
                         char_string  key_object(keyHashStr.c_str(), alloc_inst3);
                         ++count;
                  }
           }
    }
SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105
rban
  • 3
  • 2
  • Define `crash`. Does it throw an exception? Does the process die? – Mark Jansen Sep 25 '15 at 11:35
  • If an exception is thrown there's probably a reason behind it, trying the same thing over and over again isn't going to help much. "The definition of insanity is doing the same thing over, but expecting different results". Instead try to understand *why* the exception was thrown, and what could be done to prevent it. – Some programmer dude Sep 25 '15 at 11:35
  • @MarkJansen : By crash I mean the process is dying – rban Sep 25 '15 at 11:55
  • Well, the inifinite loop where you are constantly creating new objects if it fails once is certainly not gonna help... – Mark Jansen Sep 25 '15 at 13:19

2 Answers2

1

I also had the similar problem. The process was crashing inside boost. In my case when two processes tried to create or open a particular shared memory region simultaneously then one of the processes crashed afterward in the "for" loop. I used "boost named mutex" while creating a shared memory region. That worked for me. If we take sehe's code then I think following modification would solve the problem.

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <string>
#include <iostream>

#define RESERVED_BUFFER_SIZE_WRITE (8 * 0x0100000)

namespace bip = boost::interprocess;

//Typedefs of allocators and containers
typedef bip::allocator<char, bip::managed_shared_memory::segment_manager> char_allocator;
typedef bip::basic_string<char, std::char_traits<char>, char_allocator>   char_string;


int main()
{
    boost::interprocess::named_mutex MyBookkeeperMutex(boost::interprocess::open_or_create, "MyBookkeeperMutex");

    MyBookkeeperMutex.lock();
    bip::managed_shared_memory m_sharedMemUsage(bip::open_or_create, "MyBookkeeper", 2 * RESERVED_BUFFER_SIZE_WRITE);
    MyBookkeeperMutex.unlock();

    char_allocator alloc_inst3(m_sharedMemUsage.get_segment_manager());
    for (int count = 0; count < 100000; ++count) {
        char_string key_obect("AAAAAAAAAAAAAAAAAAAAAAA", alloc_inst3);
    }
    boost::interprocess::named_mutex::remove("MyBookkeeperMutex");
}
Abhishek
  • 26
  • 2
  • @rban see http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – sehe Sep 29 '15 at 22:44
0

I'd suggest using the open_or_create flag instead.

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <string>
#include <iostream>

#define RESERVED_BUFFER_SIZE_WRITE (8 * 0x0100000)

namespace bip = boost::interprocess;

//Typedefs of allocators and containers
typedef bip::allocator<char, bip::managed_shared_memory::segment_manager> char_allocator;
typedef bip::basic_string<char, std::char_traits<char>, char_allocator>   char_string;

int main()
{
    bip::managed_shared_memory m_sharedMemUsage(bip::open_or_create, "MyBookkeeper", 2 * RESERVED_BUFFER_SIZE_WRITE);

    char_allocator alloc_inst3(m_sharedMemUsage.get_segment_manager());
    for (int count = 0; count < 100000; ++count) {
        char_string key_obect("AAAAAAAAAAAAAAAAAAAAAAA", alloc_inst3);
    }
}

Note how this doesn't leak resources, because the destructor of the class actually runs...

sehe
  • 374,641
  • 47
  • 450
  • 633