本文介绍了当进程附加时,升级删除managed_shared_memory的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个进程,进程1创建一个提升managed_shared_memory段,进程2打开此段。然后重新启动进程1,进程1的启动具有以下

I have 2 processes, process 1 creates a boost managed_shared_memory segment and process 2 opens this segment. Process 1 is then restarted and the start of process 1 has the following,

struct vshm_remove
{
    vshm_remove() 
    { 
        boost::interprocess::shared_memory_object::remove("VMySharedMemory"); 
    }
    ~vshm_remove()
    {
        boost::interprocess::shared_memory_object::remove("VMySharedMemory"); 
    }
} vremover;



我理解当进程1开始或结束时,remove方法将在我的共享内存上调用,但shouldnt它只有删除它,如果过程2不附加它?我使用以下内容附加到进程2中的共享内存。

I understand that when process 1 starts or ends the remove method will be called on my shared memory but shouldnt it only remove it if Process 2 is not attached to it? I am attaching to the shared memory in process 2 using the following,

boost::interprocess::managed_shared_memory *vfsegment;
vfsegment = new boost::interprocess::managed_shared_memory(boost::interprocess::open_only, "VMySharedMemory");



我注意到共享内存被删除,无论进程2是否连接。 shared_memory_object :: remove

I am noticing that the shared memory is removed regardless of Process 2 being connected.

推荐答案

我不相信文档中有任何提示, / code>将失败。

I don't believe that there is any mention in the documentation that shared_memory_object::remove will fail if a process is attached.

请参阅此部分以供参考:。特别是:

Please see this section for reference: Removing shared memory. Particularly:


这意味着调用 shared_memory_object :: remove(foo)尝试删除名为foo的共享内存。

This means that a call to shared_memory_object::remove("foo") will attempt to remove shared memory named "foo" no matter what.

该函数的实现()反映此行为:

The implementation of that function (source here) reflects that behavior:

inline bool shared_memory_object::remove(const char *filename)
{
   try{
      //Make sure a temporary path is created for shared memory
      std::string shmfile;
      ipcdetail::tmp_filename(filename, shmfile);
      return ipcdetail::delete_file(shmfile.c_str());
   }
   catch(...){
      return false;
   }
}

根据我发布的生产代码的经验,已成功,呼叫 shared_memory_object :: remove ,直到我不再需要访问共享内存。

In my experience with released production code, I've had success not calling shared_memory_object::remove until I no longer need access to the shared memory.

我写了一个非常简单的示例主程序,您可能会发现有用的。它将附加,创建或删除共享内存,具体取决于运行方式。编译后,尝试以下步骤:

I wrote a very simple example main program that you might find helpful. It will attach to, create, or remove shared memory depending on how you run it. After compiling, try the following steps:


  1. 使用c运行以创建共享内存(默认为1.0K) li>
  2. 使用o运行以打开(附加到)共享内存并读取哑元数据(默认情况下,读取将每10秒发生一次)

  3. 在单独的会话中,使用r运行以删除共享内存

  4. 使用o再次尝试打开。请注意,这将(几乎肯定)失败,因为共享内存在上一步(再次,几乎肯定)删除

  5. 随意从第二步中杀掉进程

  1. Run with c to create the shared memory (1.0K by default) and insert dummy data
  2. Run with o to open ("attach to") the shared memory and read dummy data (reading will happen in a loop every 10 seconds by default)
  3. In a separate session, run with r to remove the shared memory
  4. Run again with o to try to open. Notice that this will (almost certainly) fail because the shared memory was (again, almost certainly) removed during the previous step
  5. Feel free to kill the process from the second step

至于为什么上面的步骤2可以在调用 shared_memory_object :: remove ,请参阅。具体来说:

As to why step 2 above continues to be able to access the data after a call to shared_memory_object::remove, please see Constructing Managed Shared Memory. Specifically:


  • 共享内存对象被打开。

  • 整个共享内存对象映射到进程的地址空间。

很可能,因为共享内存对象映射到进程的地址空间,共享内存文件本身不再直接需要。

Mostly likely, because the shared memory object is mapped into the process' address space, the shared memory file itself is no longer directly needed.

我意识到这是一个相当困难的例子,但我认为更具体的可能是有帮助的。

I realize that this is a rather contrived example, but I thought something more concrete might be helpful.

#include <cctype>   // tolower()
#include <iostream>
#include <string>
#include <unistd.h> // sleep()
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>

int main(int argc, char *argv[])
{
  using std::cerr; using std::cout; using std::endl;
  using namespace boost::interprocess;

  if (argc == 1) {
    cout << "usage: " << argv[0] << " <command>\n  'c'   create\n  'r'   remove\n  'a'   attach" << endl;
    return 0;
  }

  const char * shm_name = "shared_memory_segment";
  const char * data_name = "the_answer_to_everything";

  switch (tolower(argv[1][0])) {
    case 'c':
        if (shared_memory_object::remove(shm_name)) { cout << "removed: " << shm_name << endl; }
        managed_shared_memory(create_only, shm_name, 1024).construct<int>(data_name)(42);
        cout << "created: " << shm_name << "\nadded int \"" << data_name << "\": " << 42 << endl;
        break;
    case 'r':
      cout << (shared_memory_object::remove(shm_name) ? "removed: " : "failed to remove: " ) << shm_name << endl;
      break;
    case 'a':
      {
        managed_shared_memory segment(open_only, shm_name);
        while (true) { 
          std::pair<int *, std::size_t> data = segment.find<int>( data_name );
          if (!data.first || data.second == 0) {
            cerr << "Allocation " << data_name << " either not found or empty" << endl;
            break;
          }
          cout << "opened: " << shm_name << " (" << segment.get_segment_manager()->get_size()
               << " bytes)\nretrieved int \"" << data_name << "\": " << *data.first << endl;
          sleep(10);
        }
      }
      break;
    default:
      cerr << "unknown command" << endl;
      break;
  }
  return 0;
}

这篇关于当进程附加时,升级删除managed_shared_memory的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 19:28