Modify

Opened 5 years ago

Last modified 5 years ago

#7420 new Bugs

If I call managed_shared_memory() function when I create a lot of objects, it ocurrs error.

Reported by: anonymous Owned by: Ion Gaztañaga
Milestone: To Be Determined Component: interprocess
Version: Boost 1.47.0 Severity: Problem
Keywords: interprocess, shared_memeory Cc:

Description

I want to call managed_shared_memory(), when I create a lot of objects... however,it ocurrs error. In additional, it's too show to create shared memory and segment..

You can check a attached file.

Should I call managed_shared_memory() only one time?

please answer..

Attachments (1)

boost_interprocess_errorTestCode.cpp (10.7 KB) - added by mimirang@… 5 years ago.

Download all attachments as: .zip

Change History (7)

Changed 5 years ago by mimirang@…

comment:1 Changed 5 years ago by Robert Luberda <robert@…>

Hi,

We have observed a similar issue under Linux. We have recently switched from boost 1.42 to boost 1.48 and noticed that out application, which creates about 10,000 /dev/shm files, started to fail with "Too many open files" error.

It turned out the for some reason the interprocess library no longer closes file descriptors after shm_open() and mmap() calls. This is most probably caused by the following `if' that was added into managed_open_or_create_impl.hpp (the value of StoreDevice? seems to be always true)

 if(StoreDevice){
         this->DevHolder::get_device() = boost::interprocess::move(dev);
      }

The same issue exists on boost 1.50 and boost 1.51.

Sample program:

/* First set open files limit to 10
 * Then try to create 20 shm files and display number of files 
 * in /proc/self/fd after each created file */
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/lexical_cast.hpp>
#include <unistd.h>
#include <vector>
#include <stdio.h>
#include <sys/resource.h>

int main(int /*argc*/, char ** /*argv*/)
{
   // decrease limit of open files
  struct rlimit rlp = { 10, 10 };
  setrlimit(RLIMIT_NOFILE, &rlp);


  std::system("rm -f /dev/shm/ShmTest*");
  using namespace boost::interprocess;
  const  std::string fdCountStr  = "ls -1 /proc/" + boost::lexical_cast<std::string>(getpid()) + "/fd | wc -l"; 
  std::vector<managed_shared_memory*> v;

  for (int i = 0 ; i < 20; ++i)
  {
   const std::string name = "ShmTest" + boost::lexical_cast<std::string>(i);
   v.push_back(new managed_shared_memory(create_only, name.c_str(), 1024));
   std::system (fdCountStr.c_str());
  }

  return 0;
}

Output when compiled with boost 1.48:

> ./a.out 
4
5
6
7
8
9
terminate called after throwing an instance of 'boost::interprocess::interprocess_exception'
  what():  Too many open files
Aborted (core dumped)

Output when compiled with boost 1.42:

> ./a.out 
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3

comment:2 Changed 5 years ago by kdk <kdkomsdev@…>

Hi

I ran the attached program Robert Luerda on cygwin(win32/g++ (GCC) 4.5.3/boost 1.51.0) with 20,40,100 and 1000 as iteration values and no exception was thrown

Administrator@VALUED-7ZSFP29H ~ $ ./a.exe 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

comment:3 Changed 5 years ago by mimirang

Hi.

Thank you for replying the bugs. I understood that It's OK on boost 1.51.0. However, When I ran my program "boost_interprocess_errorTestCode.cpp" on boost 1.51.0(win32, Visual Studio), it has still error.

Please run "boost_interprocess_errorTestCode.cpp" with boost 1.51.0, and check the error.

comment:4 Changed 5 years ago by Ion Gaztañaga

Thanks for the report. First of all, creating so many shared memory segments it's not very likely. If you would want to emulate it with plain files, you'll need to open too many files. 10.000 managed segments at the same time, seems too high IMHO.

However, I can't remember right now the exact reason why StoreDevice? needed to be true for shared memory managed segments. It is need for xsi_shared memory and not for windows_shared_memory.

As a test, you could modify basic_managed_shared_memory (in managed_shared_memory.hpp) and change:

, private ipcdetail::managed_open_or_create_impl<shared_memory_object

, AllocationAlgorithm::Alignment>

with

, private ipcdetail::managed_open_or_create_impl<shared_memory_object

, AllocationAlgorithm::Alignment, true, false>

(that is, FileBased? = true and StoreDevice? = false)

let me know if that fixes the problem.

In Boost 1.52, mapped_region will hold a file descriptor in windows, to allow implementing blocking flush() in windows (as we need to call FlushFileBuffers?() with a file descriptor), so there will be another open file descriptor. If you know an alternative to avoid maintaining an open file descriptor only for this purpose, please let me know.

In Unix, after mmap the file descriptor can be closed, as according to POSIX:

"The mmap() function shall add an extra reference to the file associated with the file descriptor fildes which is not removed by a subsequent close() on that file descriptor. This reference shall be removed when there are no more mappings to the file."

Please let me know if you find any problems with the proposed change and/or soon to be released Boost 1.52

comment:5 Changed 5 years ago by mimirang

Hi.

Thank you for replying. I modifed basic_managed_shared_memory following your solution. (Boost 1.51.0, Win32, Visual Studio 2008)

change :


basic_managed_shared_memory

: public ipcdetail::basic_managed_memory_impl

<CharType?, AllocationAlgorithm?, IndexType? ,ipcdetail::managed_open_or_create_impl<shared_memory_object

, AllocationAlgorithm::Alignment>::ManagedOpenOrCreateUserOffset?>

, private ipcdetail::managed_open_or_create_impl<shared_memory_object

, AllocationAlgorithm::Alignment, true, false>

{

/ @cond typedef ipcdetail::basic_managed_memory_impl

<CharType?, AllocationAlgorithm?, IndexType?, ipcdetail::managed_open_or_create_impl

< shared_memory_object, AllocationAlgorithm::Alignment>::ManagedOpenOrCreateUserOffset?> base_t;

typedef ipcdetail::managed_open_or_create_impl

<shared_memory_object, AllocationAlgorithm::Alignment, true,false> base2_t;


However, It's not working. So, I modified my application program that calls mamaged_shared_memory() one time.

I hope that you fix this problem, and release new Boost 1.52.

Thank you so much to report and give me tips.

comment:6 Changed 5 years ago by Robert Luberda <robert@…>

Hi,

I did the exactly the same change as mimirang (i.e. added the "true, false" arguments in 3 places) and it fixes the issue for me. So it seems my issue is in fact different than the originally reported one. Sorry about not creating a new report for this.

I agree that using over 10000 shared memory segments might seem quite unlikely, but we do this in our project - we use different kind of segments for different kind of data shared amongst several instances of application.

Thanks, Robert

Modify Ticket

Change Properties
Set your email in Preferences
Action
as new The owner will remain Ion Gaztañaga.

Add Comment


E-mail address and name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.