6 Ekim 2019 Pazar

mmap metodu

Giriş
Şu satırı dahil ederiz.
#include <sys/mman.h>
İmzası şöyle.
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); 
Bu çağrı neticesinde, yaratılan shared memory alanını, kendi uygulamamızda kullanabiliriz. mprotect ile sayfanın haklarını değiştirebiliriz.

Eğer Memory Mapped File yapmak istersek mmap ile Memory Mapped File yazısına bakabilirsiniz.

Örnek
Şöyle yaparız
mmap(
     NULL,                                /*addr*/
     321,                                 /*length*/
     PROT_EXEC | PROT_READ | PROT_WRITE,  /*prot*/
     MAP_ANONYMOUS | MAP_PRIVATE,         /*flags*/
     -1,                                  /*fd*/
     0                                    /*offset*/
)
Örnek
Şöyle yaparız. Sadece yazacağımız ve shared olan - yani diğer uygulamaların erişebileceği bir alan verir.
const int SIZE = 2048;
int  shm_fd = shm_open (...);
ftruncate (shm_fd,SIZE);
void *ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
Örnek
Şöyle yaparız. Sadece okuyacağımız ve anonim olan - yani fork() edilen uygulamarın erişebileceği - ancak private olan - yani diğer uygulamarın erişemeyeceği - bir bellek verir.
void* p = mmap(NULL, 8192,PROT_READ,MAP_ANONYMOUS|MAP_PRIVATE,-1,0);
1. Parametre - Adres
Adres parametresidir. Genelde 0 verilir.

2. Parametre  - Büyüklük
Belleğin büyüklüğünü belirtir.

3. Parametre - Haklar 
- PROT_READ : Sadece okuma hakkı verir. Bu çağrı Linux'ta aynı zamanda PROT_EXEC seçeneğinin de etkinleşmesini sağlar. Açıklaması şöyle.
Linux has an execution domain called READ_IMPLIES_EXEC, which causes all pages allocated with PROT_READ to also be given PROT_EXEC.
- PROT_WRITE :  Sadece yazma hakkı verir

4. Parametre  - flags 

MAP_POPULATE : Açıklama yaz

MAP_SHARED : Memory Mapped I/O ile IPC yapmak için bu bayrağı kullanmak gerekir

MAP_PRIVATE : Memory Mapped I/O ile IPC yapmak istenmiyorsa bu bayrağı kullanmak gerekir. Açıklaması şöyle.
MAP_PRIVATE
    ...
    It is  unspecified  whether changes made to the file
    after the mmap() call are visible in the mapped region.
MAP_ANONYMOUS :
Açıklaması şöyle.
MAP_ANONYMOUS
The mapping is not backed by any file; its contents are initialized to zero. The fd and offset arguments are ignored; however, some implementations require fd to be -1 if MAP_ANONYMOUS (or MAP_ANON) is specified, and portable applications should ensure this. The use of MAP_ANONYMOUS in conjunction with MAP_SHARED is only supported on Linux since kernel 2.4.
fork() edilen child uygulama ile belleği paylaşmamızı ancak başka uygulamaların erişememesini sağlar.
Örnek
Şöyle yaparız.
mmap(NULL, n_bytes, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
5. file descriptor
Eğer bir dosyayı belleğe yüklemek istiyorsak kullanılır. Eğer MAP_ANONYMOUS bayrağı ile kullanıyorsak -1 verilir.

Çağrı Sonucu
Bu çağrı void * döndüğü için shared memory alanı yazılacak veya okunacak veri yapısına cast edilebilir. Örnek:
struct MyStruct
{
    int s_int;
    char s_str[64];
};

void* mem = mmap ...
struct MyStruct* sp = (struct MyStruct*)mem;

/* writing */
sp->s_int = 3;
strcpy(sp->s_str, "Hello");

/* reading */
printf("s_int=%d, s_str=%s\n", sp->s_int, sp->s_str);
Ya da istersek I/O metodlarını da kullanabiliriz.
sprintf(mem, "%d", value);
mem += sizeof(value);

Hiç yorum yok:

Yorum Gönder