Üye Kayıt Üye Giriş

Ortak Bellek Alanının Silinmesi ve shmctl Fonksiyonu


Ortak Bellek Alanının Silinmesi ve shmctl Fonksiyonu

Daha önceden de ele alındığı gibi ortak bellek alanı shmget fonksiyonuyla yaratılmakta ve
shmat fonksiyonuyla gerçek tahsisat yapılmaktadır. Bu IPC nesnesinin yaratılmasıyla belleğin
tahsis edilmesi farklı işlemlerdir. Eğer process shmdt ile detach işlemi yapmadıysa process
sonlandığında otomatik detach işlemi yapılır, ancak IPC nesnesi silinmez. IPC nesnesinin
silinmesi shell üzerinden manual olarak ya da xxxctl fonksiyonlarıyla yapılmaktadır.
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
Fonksiyonun üçüncü parametresi shmid_ds türünden bir yapının adresidir. İkinci parametre
IPC_STAT ise ortak bellek alanı hakkındaki bilgiler üçüncü parametresiyle belirtilen yapıya
yerleştirilir. shmid_ds yapısında değerli pek çok bilgi vardır. İkinci parametre IPC_SET ise
tam ters bir işlem yapılır. Yani yapı içerisindeki bilgiler IPC nesnesine yerleştirilir. Ancak bu
yapının yalnızca shm_perm elemanı değiştirilebilmektedir. İkinci parametre IPC_RMID ise
IPC nesnesi silinir. Bu durumda üçüncü parametrenin bir önemi kalmaz 0 geçilebilir.
Sınıf çalışması: Aşağıda belirtilen ortak bellek alanı uygulamasını yazınız.


1) İki program söz konusudur. A programı ortak bellek alanını yaratır ve B programı aynı
anahtarı kullanarak bu bellek alanını açar.
2) 50 byte’lık bir ortak bellek alanı yaratılacaktır. A programı döngü içerisinde klavyeden bir
yazı isteyecek ve bunu ortak bellek alanına yerleştirecektir. Bu sırada B programı


while (1)
pause();


biçiminde bekler. A programı ortak bellek alanına klavyeden alınan yazıyı yazdıktan sonra
SIGUSR1 oluşturacak, B programı da bu signal’i ele alarak ortak bellek alanındaki yazıyı
ekrana yazdıracaktır.
3) A programı "quit" girildiğinde quit yazısını da ortak bellek alanına yerleştirir ve döngüden
çıkar. IPC detach yapıp nesnesini de siler. B programı ise quit yazısını aldıktan sonra signal
fonksiyonu içerisinde programı sonlandırır.


/* shm_a.c */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHM_KEY 123456
void del_shm(int shmid);
int main(void)
{
int shmid, fifofd;
pid_t pid;
char *padr;
if ((fifofd = open("pid", O_RDWR)) < 0) {
perror("open");
exit(EXIT_FAILURE);
}
if (read(fifofd, &pid, sizeof(pid_t)) < 0) {
perror("read");
exit(EXIT_FAILURE);
}
close(fifofd);
shmid = shmget(SHM_KEY, 50, IPC_CREAT|0666);
if (shmid < 0) {
perror("shmget");
exit(EXIT_FAILURE);
}
padr = (char *) shmat(shmid, NULL, 0);
if (padr < 0) {
perror("shmat");
del_shm(shmid);
exit(EXIT_FAILURE);
}
for (;;) {
printf("Text: ");
gets(padr);
kill(pid, SIGUSR1);
if (!strcmp(padr, "quit"))
break;
}
del_shm(shmid);
return 0;
}
void del_shm(int shmid)
{
if (shmctl(shmid, IPC_RMID, NULL) < 0) {
perror("shmctl");
exit(EXIT_FAILURE);
}
}
/* shm_b.c */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHM_KEY 123456
void sigusr1_handler(int sno);
char *g_padr;
int main(void)
{
int shmid, fifofd;
pid_t pid;
if ((fifofd = open("pid", O_RDWR)) < 0) {
perror("open");
exit(EXIT_FAILURE);
}
pid = getpid();
if (write(fifofd, &pid, sizeof(pid_t)) < 0) {
perror("read");
exit(EXIT_FAILURE);
}
close(fifofd);
shmid = shmget(SHM_KEY, 0, 0);
if (shmid < 0) {
perror("shmget");
exit(EXIT_FAILURE);
}
g_padr = (char *) shmat(shmid, NULL, 0);
if (g_padr < 0) {
perror("shmat");
exit(EXIT_FAILURE);
}
if (signal(SIGUSR1, sigusr1_handler) < 0) {
perror("signal");
exit(EXIT_FAILURE);
}
while (1)
pause();
return 0;
}
void sigusr1_handler(int sno)
{
if (!strcmp(g_padr, "quit"))
exit(EXIT_SUCCESS);
puts(g_padr);
}

 

Bilgisayar Dershanesi Ders Sahibi;
Bilgisayar Dershanesi

Yorumlar

Yorum Yapabilmek İçin Üye Girişi Yapmanız Gerekmektedir.

ETİKETLER