Linux Sistem Programlama
  • Kapak
  • Önsöz
  • Sistem Programlamaya Giriş
    • Tarihçe
    • Standartlar
    • Sistem Çağrıları
    • API ve ABI
  • Linux Çekirdeği
  • Kabuk
  • Dosya Sistemi
  • Kullanıcı, Grup ve Erişim Yetkileri
  • Process Kavramı
  • Dosya İşlemleri
  • IO Modelleri
    • Senkron IO
    • Asenkron IO
  • Sinyaller
    • Temel Kavramlar
    • Sinyal Yakalama ve Gönderme
    • Signal-Safe Kavramı
    • Sinyal Kümeleri
    • Sinyal Bloklama
    • Sinyal İle Birlikte Veri Gönderimi
    • Sinyal ve Core Dump
    • RealTime Sinyaller
    • File Descriptor Üzerinden Sinyal İşleme
    • Genel Değerlendirme
  • Thread Kullanımı
    • Thread Oluşturma
    • Thread Türleri
    • Thread Sonlandırma
    • Mutex Kullanımı
    • SpinLock & Mutex Karşılaştırması
    • Futex
  • Semafor Kullanımı
    • Semafor ve Mutex Karşılaştırması
    • Semafor Türleri
    • Semafor Operasyonları
  • Shared Memory Kullanımı
  • Memory Mapped IO
  • Soket Kullanımı
    • Soket API
    • TCP Soketleri
    • UDP Soketleri
    • UNIX Soketleri
    • Birden Çok İstemciyle Çalışma
  • Timer Kullanımı
    • Basit Timer Yapıları
    • POSIX Timer API
    • Event Loop İçinde Kullanım
  • Daemon Oluşturma
  • Capabilities API
  • Paylaşımlı Kütüphaneler
    • Kütüphane Gereksinimi
    • Statik Kütüphaneler
    • Kod Referanslarının Ele Alınması
    • Paylaşımlı Kütüphanelerin Oluşturulması
    • Dinamik Yükleme
    • Derleme Zamanında Kütüphanelerin Aranması
    • Çalışma Zamanında Kütüphanelerin Aranması
    • Statik ve Dinamik Kütüphanelerin Beraber Kullanılması
    • Versiyon Yönetimi
  • Process'ler Arası Haberleşme
  • Memory Allocation
  • Memory Barriers
  • Hata Ayıklama Yöntemleri
    • GNU Debugger
    • Strace
  • GNU Build Sistemi Araçları
    • Make
    • Autoconf, Automake
  • Ek Bölümler
    • Derleyici Optimizasyonları
    • Clang ve LLVM
    • İçsel ve Anonim Fonksiyonlar
      • İçsel Fonksiyonlar
      • Anonim Fonksiyonlar
    • FreeTDS ile SqlServer Bağlantısı
  • Kaynak Dosyalar
Powered by GitBook
On this page
  • shm_open
  • Örnek: Shared Memory Oluşturma
  • Örnek: Shared Memory Yazma
  • Kullanım
  • shm_unlink
  • Örnek

Was this helpful?

Shared Memory Kullanımı

  • POSIX shared memory kullanımı, System V shared memory modeline göre avantajları nedeniyle özellikle yeni uygulamalarda daha fazla tercih edilmektedir.

  • Linux 2.4 çekirdeği ile birlikte desteklenmeye başlanmıştır.

  • Semafor kullanımına benzer şekilde, POSIX shared memory objeleri de Linux altında tmpfs dosya sistemi ile /dev/shm dizini altına bağlanmış halde tutulur.

  • Bu dizin tmpfs türünde öntanımlı olarak, mevcut sistem belleğinin maksimum yarısını kullanacak şekilde bağlanır ancak mount işleminde parametre vererek bu değeri değiştirmek mümkündür.

shm_open

  • shm_open fonksiyonu, standart kütüphanedeki open fonksiyonuyla aynı arayüze sahiptir.

  • Parametre olarak dosya ismi, işleme dair ayarlanan opsiyonlar ve açılacak kaynak üzerindeki erişim yetkilerini alır.

  • open fonksiyonundakine benzer şekilde O_CREAT, O_EXCL, O_RDONLY, O_RDRW ve O_TRUNC opsiyonlarının bir veya birkaçı birleştirilerek parametre olarak verilebilir.

  • Geriye dönen file descriptor referansı üzerinden fstat fonksiyonuyla yapacağımız kontroller ile, shared memory alanının büyüklüğünü öğrenebiliriz. Yeni açılan shared memory alanlarının boyutu başlangıçta sıfırdır.

  • Memory map işlemini yapmadan önce, ftruncate fonksiyonu ile shared memory alanının boyutunu istediğimiz değere ayarlayabiliriz. Bu işlem üretilen alandaki bellek bölgesini '\0' değerleriyle doldurur.

Örnek: Shared Memory Oluşturma

/* shm_create.c */
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "common.h"

static void usageError(const char *progName)
{
    fprintf(stderr, "Usage: %s [-cx] name size [octal-perms]\n", progName);
    fprintf(stderr, "-c Create shared memory (O_CREAT)\n");
    fprintf(stderr, "-x Create exclusively (O_EXCL)\n");
    exit(EXIT_FAILURE);
}

int main(int argc, char *argv[])
{
    int flags, opt, fd;
    mode_t perms;
    size_t size;
    void *addr;
    flags = O_RDWR;
    while ((opt = getopt(argc, argv, "cx")) != -1) {
        switch (opt) {
        case 'c':
            flags |= O_CREAT;
            break;
        case 'x':
            flags |= O_EXCL;
            break;
        default:
            usageError(argv[0]);
        }
    }
    if (optind + 1 >= argc)
        usageError(argv[0]);

    size = getLong(argv[optind + 1], GN_ANY_BASE, "size");
    perms = (argc <= optind + 2) ? (S_IRUSR | S_IWUSR) :
    getLong(argv[optind + 2], GN_BASE_8, "octal-perms");

    /*  Create shared memory object and set its size */
    fd = shm_open(argv[optind], flags, perms);
    if (fd == -1)
        errExit("shm_open");

    if (ftruncate(fd, size) == -1)
        errExit("ftruncate");

    /*  Map shared memory object */
    addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (addr == MAP_FAILED)
            errExit("mmap");

    exit(EXIT_SUCCESS);

}

Örnek: Shared Memory Yazma

/* shm_write.c */
#include <fcntl.h>
#include <sys/mman.h>
#include "common.h"

int main(int argc, char *argv[])
{
    int fd;
    size_t len;
    char *addr;
    /*  Size of shared memory object */

     if (argc != 3 || strcmp(argv[1], "--help") == 0)
       usageErr("%s shm-name string\n", argv[0]);

    fd = shm_open(argv[1], O_RDWR, 0);

    if (fd == -1)
        errExit("shm_open");

    /*  Open existing object */
    len = strlen(argv[2]);
    if (ftruncate(fd, len) == -1)
        /*  Resize object to hold string */
        errExit("ftruncate");

    printf("Resized to %ld bytes\n", (long) len);
    addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (addr == MAP_FAILED)
        errExit("mmap");
    if (close(fd) == -1)
        errExit("close");
    /*  'fd' is no longer needed */
    printf("copying %ld bytes\n", (long) len);
    memcpy(addr, argv[2], len);
    /*  Copy string to shared memory */
    exit(EXIT_SUCCESS);
}

Kullanım

  • İlk örnekteki uygulamayı kullanarak, 4 byte uzunluğunda deneme1 adında bir shared memory alanı oluşturalım:

    ./shm_create -c deneme1 4

  • Ardından hexdump ile ilgili dosyaya bakalım:

    hexdump -C /dev/shm/deneme1 00000000 00 00 00 00

  • Şimdi bu shared memory alanını genişleterek başka bir süreçten içerisine veri aktarıp hexdump ile kontrol edelim:

./shm_write deneme1 "Örnek bir metin"
Resized to 16 bytes
copying 16 bytes

hexdump -C /dev/shm/deneme1
00000000  c3 96 72 6e 65 6b 20 62  69 72 20 6d 65 74 69 6e  |..rnek bir metin|

shm_unlink

  • Shared memory alanını kaldırmak istediğimizde kullanılır.

  • shm_unlink işlemi sonrası, ilgili alanını memory-map yöntemiyle kullanmakta olan diğer süreçlerin mapping bilgilerini etkilemez. İlgili süreçlerde ayrıca munmap fonksiyonu çağrılmalıdır.

  • Shared memory alanını kullanan tüm süreçler shm_unlink yaptıktan veya sonlandıktan sonra, işletim sistemi tarafından ilgili alan tamamen kaldırılır.

Örnek

/* shm_remove.c */
#include <fcntl.h>
#include <sys/mman.h>
#include "common.h"

int main(int argc, char *argv[])
{
    if (argc != 2 || strcmp(argv[1], "--help") == 0)
            usageErr("%s shm-name\n", argv[0]);
    if (shm_unlink(argv[1]) == -1)
            errExit("shm_unlink");
    exit(EXIT_SUCCESS);
}
PreviousSemafor OperasyonlarıNextMemory Mapped IO

Last updated 5 years ago

Was this helpful?