27 Mart 2018 Salı

shmget ile Shared Memory

Giriş
Şu satırları dahil ederiz.
#include <sys/ipc.h>
#include <sys/shm.h>
shmget() ve shmat(), POSIX değil System V metodları. Dolayısıyla mümkünse kullanılmamalı.

Bu yöntemde istenilen büyüklükte bir file desciptor yaratılıyor. Bu file desciptor, shmat() ile uygulamamıza dahil ediliyor. İskelet olarak şöyle yaparız.
char test[]="test";
key_t shkey = 2404;

int shID = shmget (shkey, sizeof(char)*(strlen(test)+1), IPC_CREAT | 0666);
char * shptr = shmat (shID, 0, 0);
memcpy (shptr, &test, strlen(test)+1);
....

shmdt (shptr);
shmget metodu - shared memory create
İmzası şöyle.
int shmget (key_t key, size_t size, int shmflg);
key_t yapısı
shmget() metoduna geçilen ilk parametre key_t yapısı. Bu parametre normalde unique bir anahtar olmalı. Ancak fork() vs gibi birbirlerinden kalıtan programlar arasında paylaşılacak bir bellek yaratmak istersek, IPC_PRIVATE kullanırız. Şöyle yaparız.
if ((shared_mem_id = shmget (IPC_PRIVATE, shm_size, 0660)) < 0)
Eğer istersek anahtarı üretmek için ftok kullanılabilir. İmzası şöyle. pathname ile verilen yol erişilebilir olmalı.
key_t ftok(const char *pathname, int proj_id);
Şöyle yaparız.
key_t key= ftok ("demo.c", 'R');
Şöyle yaparız.
key_t key = ftok (".",'b');
Örnek - key_t olarak IPC_PRIVATE
Yeni bir bellek alanı yaratmak için şöyle yaparız.
int shmid = shmget(IPC_PRIVATE, nbytes, IPC_CREAT | 0777);
int* new_array = (int*)shmat(shmid, NULL, 0);
ÖrnekŞöyle yaparız.
int shmid = shmget (key, 1000, IPC_CREAT | IPC_EXCL | 644);
Haklar şöyle tanımlanır.
int shmid = shmget(key, 4096, 0777 | IPC_CREAT);
Çağrı başarılı ise 0 döner. Hata kontrolu için şöyle yaparız.
int smhid;

if ((shmid = shmget(key,1000, IPC_CREAT | 0666)) < 0)
{
  perror("SHMGET");
  exit(1);
}
Şöyle yaparız.
if ((shmid = shmget(key, 1024, IPC_CREAT)) == -1)
  error("ERROR");
shmat metodu - shared memory attach
İmzası şöyle.
void *shmat(int shmid, const void *shmaddr, int shmflg);
Çağrı başarılı ise -1'den farklı bir değer döner. Hata kontrolü için şöyle yaparız.
char *shm;
if ((shm = shmat (shmid, NULL, 0)) == (char *) -1) {
  //error
}
Örnek
Elimizde şöyle bir kod olsun.
#define MAX_CHAR    10
typedef struct Foo
{
  char tab[5][MAX_CHAR];

} Foo;
Şöyle yaparız.
Foo *foo;

if((foo = shmat(shmid, NULL, 0)) == (Foo *) -1)
{
  perror("SHMAT");
  exit(1);
}
Şöyle yaparız
snprintf(foo->tab[0],MAX_CHAR,"%s","abnb");
snprintf(foo->tab[1],MAX_CHAR,"%s","bcde");
snprintf(foo->tab[2],MAX_CHAR,"%s","c");
snprintf(foo->tab[3],MAX_CHAR,"%s","d");
snprintf(foo->tab[4],MAX_CHAR,"%s","e");
Örnek
Yazmak için şu şekilde yapmamalıyız.
int a[] = { 1, 2, 3};
shm = a;

shmdt metodu - shared memory detach
Şöyle yaparız.
shmdt (shmid);
shmctl metodu - shared memory control
Şöyle yaparız.
shmctl (shmid, IPC_RMID, 0);

Hiç yorum yok:

Yorum Gönder