9 Ocak 2018 Salı

interprocess shared_memory_object Sınıfı

Giriş
Şu satırı dahil ederiz.
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
shared memory yaratmak için kullanılır. shared_memory_object ile yaratılan bellek mapped_region ile uygulamaya dahil edilir.

constructor ve interprocess_exception
Constructor bip::interprocess_exception fırlatabilir. Şöyle kullanmak gerekir.
bip::shared_memory_object::remove("...");
try {

  shared_memory_object shm (...);  ...
}
catch (bip::interprocess_exception &ex) {
  ...
}
Özellikle Windows'ta Event Logger'da ID'si  6005 olan bir kayıt istiyor. Yoksa bu exception atılıyor. Çözüm bu sınıfı kullanmadan önce böyle bir kayıt yaratmak. Şöyle yaparız.
bool fixBoostIpcSharedMem6005issue() const
{
  bool result = false;

  HANDLE hEventLog = ::RegisterEventSourceA(NULL, "EventLog");
  if(hEventLog)
  {
    const char* msg = "simple boost shared memory fix for 6005";

    if(::ReportEventA(hEventLog, EVENTLOG_INFORMATION_TYPE, 0, 6005,
                      NULL, 1, 0, &msg, NULL))
      result = true;

      ::DeregisterEventSource(hEventLog);
    }

    return result;
}
constructor - mode + name + access permission
mode için create_only, open_or_create_ open_only seçenekleri kullanılabilir.
Nesne ilk yaratıldığında büyüklüğü 0'dır. truncate () metodu ile büyüklük belirtilir.

Örnek
İstemci için şöyle yaparız.
bip::shared_memory_object shm
   (bip::open_only                  //only open
   ,"shared_memory"                 //name
   ,bip::read_write                 //read-write mode
   );

Örnek
Sunucu için şöyle yaparız.
bip::shared_memory_object shm
   (bip::create_only                //create
   ,"shared_memory"                 //name
   ,bip::read_write                 //read-write mode
   );
operator = metodu
Sunucu tarafında okuma yazma amaçlı bir bellek alanı yaratmak için şöyle yaparız.
bip::shared_memory_object shm;

try {
  bip::permissions perm;
  bip::perm.set_unrestricted ();
  shm = bip::shared_memory_object(
            bip::create_only,
            "...", //name
            bip::read_write, perm);
}
catch(const bip::interprocess_exception& ex) {
  ...
}
remove metodu
Bellek alanını yok etmek için şöyle yaparız.
bip::shared_memory_object::remove ("shared_memory");

Uygulamamız açılırken bellek alanı mevcutsa silmek ve de uygulama sonlanırken otomatik olarak yok etmek için şöyle yardımcı bir sınıf kullanabiliriz.
struct shm_remove
{
  shm_remove()  {bip::shared_memory_object::remove ("shared_memory"); }
  ~shm_remove() {bip::shared_memory_object::remove("shared_memory"); }
} remover;
truncate metodu
Belleğin uzunluğunu belirler. 
Örnek
Şöyle yaparız.
//Set size to 10,0000
bipi::shm.truncate (10000);
Örnek
Sunucu tarafında şöyle yaparız.
#include <iostream>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>

namespace bi = boost::interprocess;

static char const* const SHM_NAME = "sotest-5b4f4154-0c7a-48f4-9be6-33b99094cea4";

int main(int argc, char** argv) {

  bi::shared_memory_object shm(bi::open_or_create, SHM_NAME, bi::read_write);

  shm.truncate(sizeof(int) * std::atoi(argv[1]));
  bi::mapped_region reg(shm, bi::read_write);

  int* p = reinterpret_cast<int*>(reg.get_address());

  for(int i = 0; i < std::atoi(argv[1]); ++i)
    p[i] = i;

  std::cout << "Truncated and filled to " << reg.get_size() << "\n";
  
}
İstemci tarafında şöyle yaparız. Int'e reinterpret_cast yaptığımız için bellek büyüklüğünü 4 ile bölmek gerekir.
#include <iostream>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>

namespace bi = boost::interprocess;

static char const* const SHM_NAME = "sotest-5b4f4154-0c7a-48f4-9be6-33b99094cea4";

int main(int argc, char** argv) {
  bi::shared_memory_object shm(bi::open_only, SHM_NAME, bi::read_only);
  bi::mapped_region reg(shm, bi::read_only, 0);

  size_t N = reg.get_size() / 4;
  int const* p = reinterpret_cast<int const*>(reg.get_address());

  size_t index;
  while (std::cout << "Please input index: " && std::cin >> index) {
  if (index < N)
    std::cout << "Integer @" << index << " is " << p[index] << "\n";
  else
    std::cout << "Index " << index << " out of bounds [0.." << N << ")\n";
  }
  std::cout << "Bye\n";
}

Hiç yorum yok:

Yorum Gönder