Bellek Eşlemli G/Ç
Önceki XIII. Oylum - Düşük Seviyeli Girdi ve Çıktı Sonraki
Bellek Eşlemli G/Ç
Günümüz işletim sistemlerinde, bir dosyayı bir bellek bölgesine eşlemek mümkündür. Bu yapıldığında dosyaya yazılım içinden bir dizi gibi erişilebilir.
Yazılımın bir dosyanın sadece yüklü bölümlerine erişim anlamında bu işlem read veya write ile yapılan işlemlerden daha verimlidir. Henüz belleğe yüklenmemiş parçalara bellek sayfalarının takaslanmasına benzer bir yolla erişilir.
Belleğe eşlenmiş sayfalar, fiziksel bellek azaldığında tekrar dosyasında saklanabilir, belleğe eşlenmiş dosyaların boyutları büyüdükçe hem fiziksel bellekte hem de takas alanında eşlenebilir. Tek sınır adres alanıdır. Teorik sınır 32 bitlik makinelerde 4GB'dır. Başka amaçlarla ayrılan alanlardan dolayı gerçek sınır daha küçük olabilir. LFS arayüzü kullanan 32 bitlik dosya sistemlerinde dosya boyu 64 bitlik olabildiğinden 2GB ile sınırlı değildir (konumların işaretli tamsayılar olması halinde adreslenebilir alan 4GB'ın yarısına düşebilir).
Bellek eşleme, bellekte sadece sayfalarla çalışır. Bu bakımdam, eşleşme adresleri sayfalara hizalanmış ve uzunluk değerleri de buna göre yuvarlanmış olmalıdır. Makinede kullanılan sayfa boyutlarını saptamak için
size_t page_size = (size_t) sysconf (_SC_PAGESIZE);
kullanılabilir. Bu işlevler sys/mman.h başlık dosyasında bildirilmiştir.
void *mmap
(void  *adres,
 size_t uzunluk,
 int    izinler,
 int    seçenekler,
 int    dosyatanıtıcı,
 off_t  konum)
işlev
mmap işlevi dosyatanıtıcı ile açılan dosya için yeni bir eşlem oluşturur. Eşlem (konum)'dan başlar, (konum + uzunluk - 1) de biter. dosyatanıtıcı ile belirtilen dosya için dosya kapatıldığında bile kaldırılmayan yeni bir referans oluşturur.
adres ile eşlem için tercih edilen adres belirtilir. NULL tercih belirtilmediğini gösterir. Adreste evvelce bir eşlem varsa özdevinimli olarak kaldırılır. MAP_FIXED seçeneği kullanmasanızda belirttiğiniz adres yine de değiştirilmeyebilir.
izinler ne çeşit erişime izin verildiğini belirten seçenekleri içerir. Bunlar sırayla okuma, yazma ve çalıştırma izinlerini belirten PROT_READ, PROT_WRITE ve PROT_EXEC seçenekleri olabilir. Belirtilmeyen bir iznin kullanılmaya çalışılması bir parçalama arızasına (segfault) yol açacaktır (bkz. Yazılım Hatalarının Sinyalleri).
Çoğu donanım tasarımının okuma izni olmadan yazma iznini desteklemediğini ve çoğunun okuma ve çalıştırma izinleri bakımından bir ayrım yapmadığını aklınızdan çıkarmayın. Bu bakımdan, istediğinizden daha geniş yetkilere sahip olabileceğiniz gibi sadece yazılabilir olarak belirttiğiniz dosyalara PROT_READ kullanmadığınız takdirde erişemeyebileceğinizi de unutmayın.
seçenekler eşlemin doğasını denetleyen seçenekleri içerir. Burada MAP_SHARED veya MAP_PRIVATE seçeneklerinden biri belirtilmelidir.
Bunlar:
MAP_PRIVATE
Eşlemle ilgili dosyaya yazılamasa da bellek bölgesine yazılabileceğini belirtir. Bunun yerine, süreç için bir kopya yapılır ve normal olarak bellek azsa bölge takaslanır. Başka hiçbir süreç değişiklikleri görmez.
Özel eşlemler üzerlerine yazıldıklarında fiilen sıradan belleğe konulduğundan eğer bu kipi PROT_WRITE ile kullanıyorsanız eşlemlenmiş bölgenin tamamının kopyası için yeterli sanal bellek olmalıdır.
MAP_SHARED
bölgeye yapılan yazmaların dosyaya da yazılacağını belirtir. Değişiklikler aynı dosyayı eşlemlemiş olan diğer süreçlerle anında paylaşılacaktır.
Asıl yazma işlemlerinin herhangi bir anda olabileceğini unutmayın. Diğer süreçlerin geleneksel G/Ç işlemlerini kullanarak dosyanın tutarlı bir görünümünü almaları önemliyse, aşağıda açıklanan msync işlevini kullanmanız gerekir.
MAP_FIXED
Sistemin eşlem adresi olarak adres ile belirtilen adresi kullanması için zorlar. Bu olmazsa işlev başarısız olur.
MAP_ANONYMOUS
MAP_ANON
Sisteme, bir dosyaya bağlı olmayan bir anonim eşlem oluşturmasını söyler. dosyatanıtıcı ve konum yoksayılır ve bölge sıfırlarla ilklendirilir.
Anonim eşlemler bazı sistemlerde özdevimli ayırma yapılabilen bellek bölgesinin genişletilmesinde temel ilkel olarak kullanılır. Ayrıca bir dosya oluşturmadan çok sayıda görev arasında veri paylaşmak için de kullanışlıdır.
Bazı sistemlerde büyük bellek blokları ile çalışırken özel anonim eşlemleri kullanmak malloc kullanmaktan daha verimlidir. GNU C sisteminde malloc gerektiği takdirde özdevinimli olarak mmap işlevini kullanır.
mmap normalde yeni eşlemin adresi ile döner. -1 dönüş değeri bir hata oluştuğunu belirtir.
Olası hatalar:
EINVAL
Ya adres işe yaramaz ya da belirtilen seçenekler tutarsız
EACCES
dosyatanıtıcı belirtilen izinler ile açılmadı
ENOMEM
Ya işlem için yeterli bellek yok ya da süreç, adres alanı dışında
ENODEV
Bu dosya belleğe eşlemlenen türde değil
ENOEXEC
Dosya belleğe eşlemlemeyi desteklemeyen bir dosya sisteminde
void *mmap64
(void   *adres,
 size_t  uzunluk,
 int     izinler,
 int     seçenekler,
 int     dosyatanıtıcı,
 off64_t konum)
işlev
mmap64 işlevi konum parametresinin off64_t türünde olması dışında mmap işlevine eşdeğerdir. 32 bitlik sistemlerde bu, tanıtıcısı dosyatanıtıcı olan dosyanın 2GB'dan büyük olabilmesini mümkün kılar. dosyatanıtıcı, open64 veya fopen64 ve freopen64 çağrılarından dönen bir tanıtıcı olmalıdır.
Kaynak dosyaları _FILE_OFFSET_BITS == 64 ile derlenmişse bu işleve mmap ismiyle erişilir. Yani, derleme sırasında 64 bitlik yeni arayüz eski arayüzün yerine geçer.
int munmap
(void  *adres,
 size_t uzunluk)
işlev
munmap işlevi (adres)'ten (adres + uzunluk)'a kadar olan eşlemi siler. uzunluk eşlemin uzunluğu olmalıdır.
Aralık içinde eşlenmemiş alanlar olabilir, bu şekilde çok sayıda eşlem tek bir komutla silinebilir. Ayrıca mevcut eşlemin sadece bir bölümünü silmek de mümkündür. Ancak sadece tam sayfalar silinebilir. uzunluk sayfa sayısına denk değilse bile üste yuvarlanır.
Normal dönüş değeri sıfırdır, -1 bir hata belirtir.
Olası hata:
EINVAL
Belirtilen bellek adresi aralığı kullanıcının mmap aralığının dışında ya da sayfa hizalı değil
int msync
(void  *adres,
 size_t uzunluk,
 int    seçenekler)
işlev
Paylaşımlı eşlemler kullanılırken, silmeden önce çekirdek herhangi bir zamanda eşlemi dosyaya yazabilir. Değişmiş bir veri varsa, dosyaya bellek eşlemli olmayan G/Ç ile erişen süreçler veri dosyaya fiilen yazılana kadar bunları göremezler. Bunun olmaması için bu işlevi kullanmak gerekir.
İşlev adres'ten (adres + uzunluk)'a kadar olan bölgede çalışır. Bu bölge çok sayıda dosyanın eşlemlerini içerebileceği gibi bir dosyanın bir bölümünü içeren bir eşlem bölgesi de olabilir.
seçenekler şunları içerebilir:
MS_SYNC
Bu seçenek verinin "disk"e yazılmasını sağlar. Normalde msync işlevi geleneksel G/Ç işlemleri ile bir dosyaya erişimde son yapılan değişikliklere dosyada mevcutmuş gibi erişilmesini sağlar.
MS_ASYNC
msync'e eşzamanlamaya başlamasını söyler ama başlaması için beklemez.
msync normalde sıfır ile hata oluştuğunda -1 ile döner. Olası hatalar:
EINVAL
Ya geçersiz bir bölge belirtilmiş ya da seçenekler geçersiz
EFAULT
Bir bellek eşlemin parçası olarak bile bir eşlem yok
void *mremap
(void  *adres,
 size_t uzunluk,
 size_t yeni_uzunluk,
 int    seçenek)
işlev
Bu işlev mevcut bir bellek alanının boyunu değiştirmekte kullanılabilir. adres ve uzunluk tamamı aynı mmap deyiminde eşlemlenmiş bir bölgeyi belirtmelidir. yeni_uzunluk ile belirtilen yeni eşlem aynı karakteristik özelliklerle dönecektir.
Tek bir seçenek, MREMAP_MAYMOVE belirtilebilir. Bu, seçenek içinde belirtilmişse, sistem mevcut eşlemi silip başka bir yerde belirtilen uzunlukta yeni bir eşlem oluşturur.
Normalde yeni eşlemin adresi ile bir hata oluştuğunda ise -1 ile döner. Olası hatalar:
EFAULT
Özgün eşlemin parçası olarak bile bir eşlem yok veya bölge birden fazla farklı eşlem içeriyor
EINVAL
Belirtilen adres hizalı değil ya da uygunsuz
EAGAIN
Bölge kilitli sayfalar içeriyor, eğer genişletmek gerekirse kilitli sayfalar için sürecin özkaynak sınırı aşılabilir.
ENOMEM
Bölge yazılabilir ama özel, ayrıca genişletmek için sanal bellek yetersiz. Bundan başka, MREMAP_MAYMOVE belirtilmemişse ve genişletme başka bir eşlemli bölge ile çatışacaksa bu hata oluşacaktır.
Bu işlev sadece bir kaç sistemde kullanılabilir. İsteğe bağlı eniyilemeler gerçekleştirmek dışında bu işlev kullanılmamalıdır.
Tüm dosya tanıtıcılar bellek eşlemli olamaz. Soketler, borular ve çoğu aygıta sadece ardışık erişim mümkündür ve ayrılabilecek bir eşleme sığmaz. Ek olarak, bazı normal dosyalar da eşlemlenemez ve eski çekirdekler eşlemlemeyi hiç desteklemeyebilir. Bu bakımdan bu işlevi kullanacak yazılımların işlev başarısız olduğunda kullanılacak bir sonçare yöntemi olmalıdır. Bkz. .
int madvise
(void  *adres,
 size_t uzunluk,
 int    öneri)
işlev
Bu işlev, sisteme adres'tan başlayan uzunluk baytlık bellek bölgesinin düşünülen kullanım şekliyle ilgili bir öneri yapmak için kullanılabilir.
öneri için geçerli BSD değerleri şunlardır:
MADV_NORMAL
Bölge özel birşey yapmadan alınmalı.
MADV_RANDOM
Bölge rasgele sayfa referansları üzerinde erişilebilir olacak. Çekirdek her sayfalama hatası için en az sayıda sayfayı gerçek belleğe sayfalamalıdır.
MADV_SEQUENTIAL
Bölge ardışık sayfa referansları üzerinde erişilebilir olacak. Bu çekirdeğin bölge içindeki her sayfalama hatasından sonra bir ardışık referans umarak sürekli ileri okumaya zorlanmasına sebep olur.
MADV_WILLNEED
Bölge gerekli olacaktır. Bu bölge içindeki sayfalar çekirdek tarafından önceden gerçek belleğe sayfalanmış olmalıdır.
MADV_DONTNEED
Bölge artık gerekmeyecektir. Sayfa kaybına sebep olabilecek bir değişiklikte ya da sanal belleğe kopyalanması gerektiğinde bunun yapılmaması suretiyle çekirdek bu sayfaları serbest bırakabilir.
POSIX isimleri birazcık farklıdır ama isimler aynı anlama gelir:
POSIX_MADV_NORMAL
BSD'nin MADV_NORMAL seçeneğine karşılıktır.
POSIX_MADV_RANDOM
BSD'nin MADV_RANDOM seçeneğine karşılıktır..
POSIX_MADV_SEQUENTIAL
BSD'nin MADV_SEQUENTIAL seçeneğine karşılıktır.
POSIX_MADV_WILLNEED
BSD'nin MADV_WILLNEED seçeneğine karşılıktır.
POSIX_MADV_DONTNEED
BSD'nin MADV_DONTNEED seçeneğine karşılıktır.
Normalde msync sıfır ile döner, -1 bir hata saptandığını belirtir. Olası hatalar:
EINVAL
Ya belirtilen bölge ya da öneri geçersiz
EFAULT
Belirtilen bölgenin bir parçası olabilecek kadar bile eşlem yok
Önceki Üst Ana Başlık Sonraki
G/Ç'yı Hızlı Dağıtıp Toplama Başlangıç Girdi ve Çıktının Beklenmesi
Bir Linux Kitaplığı Sayfası