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.
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/mman.h>
shm_open ve /dev/shm ilişkisi
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
tmpfs on /dev/shm type tmpfs (rw)
shm_open
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.
If fildes refers to a shared memory object, the result of the write() function is unspecified.
Basit bir
örnek
const char *name = "SHARON";
int shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
shm_unlink
Dosyayı
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);
ftruncate
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:
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);
mmap
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
//Master uygulama için
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);
Aşağıda create ve attach metodlarının kodları var.