Posix
Posix ile shared memory kullanmak için yapılması gereken adımlar şöyle.
1. shm_open ile bir bellek yaratılır.
2. ftruncate ile bellek boyutu ayarlanır.
3. mmap ile bellek kendi uygulamamıza dahil edilir.
4. Interprocess mutex ile bellek korunarak sprintf türünden bir metod ile yazma ve okuma işlemi yapılır.
include dosyaları
Metodları kullanabilmek için şu dosyaları dahil etmek gerekiyor.
shm_open() /dev/shm dizini altında bir dosya yaratıyor. Bu dosyanın nereye mount edildiğini görmek için aşağıdaki gibi yapılabilir:
mount | grep shm
Komutun sonucunda şuna benzer bir şey görürüz
shm_open ile verilen shared memory ismi "/filename" kalıbına uymalı.
shm_open bir file descriptor dönüyor. Ancak fd'yi mmap ile kendi sayfamıza almadan kullanmak bir hata.
Dosyayı kapatır. file descriptor değil dosya ismi aldığına dikkat etmek lazım.
Bu metod master uygulama tarafından çağırılır. shm_open ile açılan dosya'nın boyunu ayarlamayı sağlar. Mutlaka yapılması gerekir. Örnek:
Hem master hem de child uygulama tarafından yapılması gerekir. Bu çağrı neticesinde, yaratılan shared memory alanını, kendi uygulamamızda kullanabiliriz. ftruncate çağrısında verilen dosya boyunun aynısını veya daha küçük bir değeri kullanmak gerekir.
mmap yazısına taşıdım
Master Uygulama Örneği
//create shared memory
int shmem_fd = shm_open("/my_shmem",
O_CREAT | O_RDWR, //Yarat ve okuma yazma hakkı al
S_IRUSR | S_IWUSR
);
//truncate memory object
ftruncate(shmem_fd, object_size)
//map shared memory to this process
void *addr = mmap(NULL,
object_size,
PROT_READ | PROT_WRITE, //Okuma ve yazma hakkı
MAP_SHARED, //IPC yapmak istiyoruz
shmem_fd,
0
);
Child Uygulama Örneği
int shmem_fd = shm_open("/my_shmem",
O_RDWR, //Okuma yazma hakkı al
0
);
//map shared memory to this process
void *addr = mmap(NULL,
object_size,
PROT_READ | PROT_WRITE, //Okuma ve yazma hakkı
MAP_SHARED, //IPC yapmak istiyoruz
shmem_fd,
0
);
mmap ve sayfa hizalaması (page alignment)
Bu kısım sadece teorik bilgi. mmap işletim sisteminin sayfaları üzerinde çalıştığı için istenilen hafıza miktarı otomatik olarak sayfa büyüklüğüne göre ayarlanır. Yani bazen istenilenden biraz daha fazla alan kullanılır.
mmap ve lazy initialization
Bu kısım da sadece teorik bilgi. mmap istenilen bellek büyüklüğünü sayfalara dokundukça ayırıyor denilmiş. Yani 4 GB'lik bellek alanı gerektikçe veriliyor.
boost
boost ile shared memory kullanmak için şu adımlar izlenmeli.
1. Önce bir shared memory alanı yaratılmalı. Bu alan bir boost::interprocess::allocator'a verilmeli.
2. boost::interprocess container yukarıda yaratılan allocator ile belleğe erişir.
3. Diğer uygulamalar ile eşzamanlılığı sağlamak için bir interprocess mutex kullanılmalı.
QT
Posix ile shared memory kullanmak için yapılması gereken adımlar şöyle.
1. shm_open ile bir bellek yaratılır.
2. ftruncate ile bellek boyutu ayarlanır.
3. mmap ile bellek kendi uygulamamıza dahil edilir.
4. Interprocess mutex ile bellek korunarak sprintf türünden bir metod ile yazma ve okuma işlemi yapılır.
include dosyaları
Metodları kullanabilmek için şu dosyaları dahil etmek gerekiyor.
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/mman.h>
shm_open ve /dev/shm ilişkisishm_open() /dev/shm dizini altında bir dosya yaratıyor. Bu dosyanın nereye mount edildiğini görmek için aşağıdaki gibi yapılabilir:
mount | grep shm
Komutun sonucunda şuna benzer bir şey görürüz
tmpfs on /dev/shm type tmpfs (rw)
shm_openshm_open ile verilen shared memory ismi "/filename" kalıbına uymalı.
Basit bir örnekIf fildes refers to a shared memory object, the result of the write() function is unspecified.
const char *name = "SHARON";
int shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
shm_unlinkDosyayı kapatır. file descriptor değil dosya ismi aldığına dikkat etmek lazım.
const char *name = "OS";
shm_fd = shm_open(name, O_RDONLY, 0666);
...
shm_unlink(name);
ftruncateBu metod master uygulama tarafından çağırılır. shm_open ile açılan dosya'nın boyunu ayarlamayı sağlar. Mutlaka yapılması gerekir. Örnek:
const int SIZE = 4096;
const char *name = "OS";
int shm_fd;
void *ptr;
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
ftruncate(shm_fd, SIZE);
ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
mmapHem master hem de child uygulama tarafından yapılması gerekir. Bu çağrı neticesinde, yaratılan shared memory alanını, kendi uygulamamızda kullanabiliriz. ftruncate çağrısında verilen dosya boyunun aynısını veya daha küçük bir değeri kullanmak gerekir.
mmap yazısına taşıdım
Master Uygulama Örneği
//create shared memory
int shmem_fd = shm_open("/my_shmem",
O_CREAT | O_RDWR, //Yarat ve okuma yazma hakkı al
S_IRUSR | S_IWUSR
);
//truncate memory object
ftruncate(shmem_fd, object_size)
//map shared memory to this process
void *addr = mmap(NULL,
object_size,
PROT_READ | PROT_WRITE, //Okuma ve yazma hakkı
MAP_SHARED, //IPC yapmak istiyoruz
shmem_fd,
0
);
Child Uygulama Örneği
int shmem_fd = shm_open("/my_shmem",
O_RDWR, //Okuma yazma hakkı al
0
);
//map shared memory to this process
void *addr = mmap(NULL,
object_size,
PROT_READ | PROT_WRITE, //Okuma ve yazma hakkı
MAP_SHARED, //IPC yapmak istiyoruz
shmem_fd,
0
);
mmap ve sayfa hizalaması (page alignment)
Bu kısım sadece teorik bilgi. mmap işletim sisteminin sayfaları üzerinde çalıştığı için istenilen hafıza miktarı otomatik olarak sayfa büyüklüğüne göre ayarlanır. Yani bazen istenilenden biraz daha fazla alan kullanılır.
mmap ve lazy initialization
Bu kısım da sadece teorik bilgi. mmap istenilen bellek büyüklüğünü sayfalara dokundukça ayırıyor denilmiş. Yani 4 GB'lik bellek alanı gerektikçe veriliyor.
boost
boost ile shared memory kullanmak için şu adımlar izlenmeli.
1. Önce bir shared memory alanı yaratılmalı. Bu alan bir boost::interprocess::allocator'a verilmeli.
2. boost::interprocess container yukarıda yaratılan allocator ile belleğe erişir.
3. Diğer uygulamalar ile eşzamanlılığı sağlamak için bir interprocess mutex kullanılmalı.
QT
//Master uygulama içinAşağıda create ve attach metodlarının kodları var.
QSharedMemory sharedMemory(QString("Shared Memory"));//key is Shared Memory
sharedMemory.create(42);//42 byte size
//Slave uygulama için
QSharedMemory sharedMemory(QString("Shared Memory"));//key is Shared Memory
sharedMemory.attach(QSharedMemory::ReadOnly);
Hiç yorum yok:
Yorum Gönder