Message Queues

Kategori: Parallel Programming , 20 Ekim 2019 , JanFranco


Message Queue'lar FIFO yani Named Pipe'lara oldukça benzemekte fakat yapı olarak Queue yapısını kullanmakta. Bir process queue oluşturabilir veya var olan bir queue'ya bağlanabilir. Ek olarak işi biten process queue'dan çıkmasına rağmen queue destroy edilmeden sistemden silinmez. Yani sistem kaynaklarını kullanmaya devam eder.

Bir process Message Queue'ye bağlanmak için msgget() fonksiyonunu kullanır:


int msgget(key_t key, int msglfg);
key parametresi queue'nin key'idir. Eğer sistemde böyle bir queue yoksa, fonksiyon bu queue'yu oluşturur. İkinci parametre fonksiyonu ne için kullanacağımızdır. Örneğin queue oluşturmak istiyorsak bu parametreyi IPC_CREAT olarak ayarlamalıyız. Bu fonksiyon doğru çalıştığında return olarak queue'nin id'sini döner. Başarısız olduğu durumlarda -1 döner.

msgget fonksiyonu parametre olarak bir key alır. Bu key'i oluşturmak için ftok fonksiyonunu kullanırız:


key_t ftok(const char *path, int id);
ftok ve msgget fonksiyonlarını anladığımıza göre artık Message Queue oluşturabiliriz:


#include <sys/msg.h>

key = ftok("/home/JanFranco/ParallelProgramming", 'b');
msqid = msgget(key, 0666 | IPC_CREAT);
Message Queue'yi oluşturduk. Bir mesaj göndermek için msgsnd() fonksiyonunu kullanacağız:


int msgsend(int msqid, const void *msgp, size_t msgsz, int msgflg);
Parametreleri açıklamak gerekirse, msqid, msgget fonksiyonundan dönen queue identifier'dır. Yani id'si gibi düşünülebilir. msgp, göndermek istediğimiz datanın adresini tutan bir pointerdır. msgsz göndereceğimiz datanın boyutudur (byte cinsinden). msgflg opsiyonel flag atama işlemleri içindir. Biz burada 0 diyerek kullanmayacağız. Öncelikle bir struct oluşturalım:


struct pirate_msgbuf {
    long mytpe;
    struct pirate_info {
        char name[30];
        char ship_type;
        int notoriety;
        int cruelty;
        int booty_value;
    } info;
};
Şimdi bu struct'tan bir obje oluşturalım ve mesaj olarak gönderelim:


#include <sys/msg.h>
#include <stddef.h>

key_t key;
int msqid;
struct pirate_msgbuf pmb = {2, {"Captain Flint", 'S', 80, 10, 12035}};

key = ftok("/home/JanFranco/ParallelProgramming", 'b');
msqid = msgget(key, 0666 | IPC_CREAT);

msgsnd(msqid, &pmb, sizeof(struct pirate_info), 0);
Mesajımızı gönderdik. Şimdi diğer process'ten bu mesajı alalım. Mesaj almak için msgrcv() fonksiyonunu kullanacağız:


int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
msgsnd() fonksiyonuna oldukça benzemekte. Tek farkı parametre olarak msgtyp almakta. msgtyp'ın fonksiyonu nasıl değiştirdiğini gösteren tablo:


msgtype		effect

Zero		Queue'deki bir sonraki mesajı al.
Positive	Queue'deki mtype == msgtype olan mesajı al.
Negative	Queue'deki mtype < |msgtype| olan ilk mesajı al.
Gönderdiğimiz mesajı alalım:


#include <sys/msg.h>
#include <stddef.h>

key_t key;
int msqid;
struct pirate_msgbuf pmb;

key = ftok("/home/beej/somefile", 'b');
msqid = msgget(key, 0666 | IPC_CREAT);

msgrcv(msqid, &pmb, sizeof(struct pirate_info), 2, 0);
Message Queue'yu ancak destroy ederek silebiliriz. Bunun için msgctl() fonksiyonunu kullanırız:


int msgctl(int msqid, int cmd, struct msqid_ds *buf);
Kullanımı şu şekildedir:


#include <sys/msg.h>
.
.
msgctl(msqid, IPC_RMID, NULL);


Sonraki Yazı: Message Queues Example
Yorumlar

Henüz bir yorum bulunmuyor.
Yorum bırakın