Üye Kayıt Üye Giriş

İsimli Semaphore Kullanımı


İsimli Semaphore Kullanımı

-İsimli semaphore kullanımı tamamen isimsizlerde olduğu gibidir. Ancak sem_init yerine
semaphore yaratmak için sem_open fonksiyonu kullanılır.
sem_t *sem_open(const char *name, int, ...);
Fonksiyonun birinci parametresi semaphore nesnesinin ismidir. İkinci parametre açış
modudur. Bu parametre O_CREAT ya da O_CREAT | O_EXCL olabilir. İkinci parametre 0
geçilebilir. Fonksiyonun üçüncü parametresi semaphore yeni yaratılmışsa erişim haklarını
belirtir. Semaphore yeni yaratılıyorsa fonksiyonun dördüncü parametresi olarak sayaç değeri
verilebilir. Fonksiyon başarılıysa semaphore nesnesinin ID değerine, başarısızsa –1 değerine
geri döner. Semaphore’u silmek için sem_unlink fonksiyonu kullanılabilir.
sem_t *sem_unlink(const char *name);
Semaphore Nesneleri ile Mutex Nesneleri Arasındaki Benzerlikler ve Farklılıklar
Mutex nesnesini her zaman lock yapan thread unlock yapabilir (Win32 sistemlerinde bir
sayaç olduğu için aynı thread mutex nesnesini birden fazla kez ele geçirebilir). Oysa
semaphore’a giren bir thread sem_post fonksiyonunu uygulamak zorunda değildir. Yani bir
thread sem_wait uygularken başka bir thread sem_post uygulayabilir. Hem mutex hem de
semaphore kritik kod oluşturmakta kullanılabilmektedir. Ancak semaphore kritik koda birden
fazla kez giriş sağlayabilir.
Semaphore’lar tipik olarak üretici-tüketici (producer-consumer) tarzı problemler için
kullanılırlar. Örneğin üretici-tüketici problemi bir üreticinin senkronizasyon eşliğinde bir yere
bir şey koyması ve tüketicinin de bunu alması biçiminde bir problemdir. Tipik olarak iki
thread tarafından paylaşılan bir alana bir thread’in bir bilgiyi yazması diğer thread’in de bilgi
yazıldıktan sonra bu bilgiyi alması uygulaması böyledir. Eğer bu işlem aynı process’in
thread’leri arasında yapılacaksa paylaşılan alan global bir nesne olabilir, semaphore’lar da
isimsiz açılabilir. Eğer farklı process’lerin thread’leri arasında işlem yapılacaksa bu durumda
paylaşılan alan (shared memory) biçiminde oluşturulmalı, semaphore da isimli olmalıdır. Bu
problemin tipik algoritması şöyledir:


sem_t g_sem1, g_sem2;
sem_init(&g_sem1, 0, 1);
/* yazan threadin sayacı başlangıçta 1 */
sem_init(&g_sem2, 0, 0);
/* okuyan threadin sayacı başlangıçta 0 */
/* thread1 (yazan thread) */
for (;;) {
sem_wait(&g_sem1);
...
sem_post(&g_sem2);

}
/* thread2 (okuyan thread) */
for (;;) {
sem_wait(&g_sem2);
...
...
sem_post(&g_sem1);
}
/* sem1.c */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
#include <semaphore.h>
#define SHMKEY 123456
int main(void)
{
sem_t *sem1;
sem_t *sem2;
int shmid, i;
int *pi;
if ((sem1 = sem_open("/home/student/sema1",
O_CREAT, 0666, 1)) == (sem_t *) -1) {
fprintf(stderr, "Cannot create semaphore!..\n");
exit(1);
}
if ((sem2 = sem_open("/home/student/sema2",
O_CREAT, 0666, 1)) == (sem_t *) -1) {
fprintf(stderr, "Cannot create semaphore!..\n");
exit(1);
}
if ((shmid = shmget(SHMKEY, sizeof(int), IPC_CREAT|0666)) == -1) {
perror("shmget");
exit(1);
}
pi = (int *) shmat(shmid, NULL, 0);
if (pi == (void *) -1) {
perror("shmat");
exit(1);
}
for (i = 0; i < 100; ++i) {
sem_wait(sem1);
*pi = i;
sem_post(sem2);
if (i == 10)
break;
}
shmdt(pi);
return 0;
}
/* sem2.c */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
#include <semaphore.h>
#define SHMKEY 123456
int main(void)
{
sem_t *sem1;
sem_t *sem2;
int shmid, i;
int *pi;
if ((sem1 = sem_open("/home/student/sema1",
O_CREAT|O_RDWR, 0666, 1)) == (sem_t *) -1) {
fprintf(stderr, "Cannot create semaphore!..\n");
exit(1);
}
if ((sem2 = sem_open("/home/student/sema2",
O_CREAT|O_RDWR, 0666, 1)) == (sem_t *) -1) {
fprintf(stderr, "Cannot create semaphore!..\n");
exit(1);
}
if ((shmid = shmget(SHMKEY, sizeof(int), IPC_CREAT|0666)) == -1) {
perror("shmget");
exit(1);
}
pi = (int *) shmat(shmid, NULL, 0);
if (pi == (void *) -1) {
perror("shmat");
exit(1);
}
for (i = 0; i < 100; ++i) {
sem_wait(sem2);
if (*pi == 10)
break;
printf("%d\n", *pi);
sem_post(sem1);
}
sem_close(sem1);
sem_close(sem2);
return 0;
}
/* sema.c */
#include <stdio.h>

#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
#include <semaphore.h>
#define SIZE 10
int g_x;
sem_t g_sem1, g_sem2;
void *ThreadFunc(void *parg)
{
for (;;) {
sem_wait(&g_sem2);
if (g_x == 10)
break;
printf("%d\n", g_x);
sem_post(&g_sem1);
}
return NULL;
}
int main(void)
{
pthread_t tid;
int i;
void *pReturn;
int result;
if (sem_init(&g_sem1, 0, 1) == -1) {
fprintf(stderr, "Cannot create semaphore!..\n");
exit(1);
}
if (sem_init(&g_sem2, 0, 0) == -1) {
fprintf(stderr, "Cannot create semaphore!..\n");
exit(1);
}
if ((result = pthread_create(&tid, NULL, ThreadFunc, NULL)) != 0) {
fprintf(stderr, "%s\n", strerror(result));
exit(1);
}
for (i = 0; i < 100; ++i) {
sem_wait(&g_sem1);
g_x = i;
sem_post(&g_sem2);
if (i == 10)
break;
}
if ((result = pthread_join(tid, NULL)) != 0) {
fprintf(stderr, "%s\n", strerror(result));
exit(1);
}
return 0;
}
poo

Bilgisayar Dershanesi Ders Sahibi;
Bilgisayar Dershanesi

Yorumlar

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

ETİKETLER