Created
March 29, 2012 16:10
-
-
Save ecylmz/2239086 to your computer and use it in GitHub Desktop.
Dining philosophers problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <pthread.h> | |
#include <unistd.h> /* sleep için */ | |
#include <stdint.h> /* uintptr_t için */ | |
/* | |
* 5 filozof yuvarlak bir masaya oturur. Masada 5 tane tabak ve 5 tane de | |
* çatal vardır. 5 kişi aynı anda yiyemeceklerini farketmeleri zor olmadı ve | |
* çatalları sırayla kullanalım dediler (tabii temizledikten sonra). | |
*/ | |
/* | |
* Hazırlıklar başlar. | |
*/ | |
/* Filozof sayısı */ | |
#define NUMP 5 | |
/* Çatallar için kardış */ | |
pthread_mutex_t fork_mutex[NUMP]; | |
/* Yemek sırasında girecekler için kardış */ | |
pthread_mutex_t eat_mutex; | |
/* Kullanılabilir boş alan için durum değişkeni tanımlanır ve ilklenir */ | |
pthread_cond_t space_avail = PTHREAD_COND_INITIALIZER; | |
/* O anda yemek yiyenlerin sayısını belirten global değişken */ | |
int num_diners = 0; | |
/* Kaçıncı filozofun yemek yediği bilgisi void argümanla alınır ve bu da philo | |
* değişkeninde saklanır. | |
*/ | |
void | |
*diner(void *arg) | |
{ | |
/* | |
* Argüman ile alınan void işaretçiden pozitif tamsayıya | |
* dönüştürmek için uygun tip tanımlanır. | |
*/ | |
uintptr_t philo; | |
/* Tip dönüşümü */ | |
philo = (uintptr_t) arg; | |
/* | |
* Filozofların kaç kez yemek yediklerini tutmak için değişken | |
* tanımlanır. | |
*/ | |
int eating = 0; | |
/* Filozoflar bize kim olduklarını söylerler */ | |
printf("I'm diner %d\n", philo); | |
/* | |
* Bir filozof 5 kere yemek yiyebilir. Kritik değişken | |
* buradaki eating değişkeni, eğer ki yemek yiyen kişi | |
* yemeğe başlamadan önce çatalları "kardış" ile kilitlemezse | |
* diğer filozoflar bu çatallara ulaşmak ister ve ortalık karışır. | |
*/ | |
while (eating < 5) { | |
printf("%d is thinking\n", philo); | |
sleep( philo / 2 ); | |
printf("%d is hungry\n", philo ); | |
/* Filozof sıraya girer ve bu sıra benim diye diğerlerine söyler. */ | |
pthread_mutex_lock(&eat_mutex); | |
/* Filozof yemeğe başlamadan önce boş yer var mı kontrolü yapar */ | |
if (num_diners == (NUMP - 1)) | |
/* Yer yoksa filozoflardan birisinin yemeğinin bitmesini | |
* bekler | |
*/ | |
pthread_cond_wait(&space_avail, &eat_mutex); | |
/* Boş yer bulan filozof sofraya oturur */ | |
num_diners++; | |
/* Sıradan sofraya geçtiği için sıradaki yeri boşaltmış oldu */ | |
pthread_mutex_unlock(&eat_mutex); | |
/* Sağındaki ve solundaki çatalları alır. */ | |
pthread_mutex_lock(&fork_mutex[philo]); | |
pthread_mutex_lock(&fork_mutex[( philo + 1) % NUMP]); | |
/* Şimdi yemeği yiyebilir */ | |
printf("%d is eating\n", philo); | |
/* Kaç kez yemek yediğini unutmamak için `eating` değişkenini | |
* arttıır. | |
*/ | |
eating++; | |
/* Filozofun yemek yeme süresi */ | |
sleep(1); | |
/* Yemek bittiyse bunu duyurur ve çatallarını geri bırakır. */ | |
printf("%d is done eating\n", philo); | |
pthread_mutex_unlock(&fork_mutex[philo]); | |
pthread_mutex_unlock(&fork_mutex[(philo + 1)%NUMP]); | |
/* Filozof yine sıraya girer. Bu seferki amacı sırada bekleyen varsa | |
* kendisinin yemeğinin bittiğini diğer filozoflara duyurmak. | |
* Sıraya girerken kullanılan `eat_mutex` kardışını kilitler. | |
*/ | |
pthread_mutex_lock(&eat_mutex); | |
/* Eğer yemek yiyenlerin sayısı 4 ise kendisi sıradan çıkacağı için | |
* Ben çıkıyorum yemekten sinyalini gönderir. | |
*/ | |
if (num_diners == (NUMP - 1)) | |
pthread_cond_signal(&space_avail); | |
num_diners--; | |
/* Şimdi sıradaki yerinden de çıkabilir */ | |
pthread_mutex_unlock(&eat_mutex); | |
} | |
/* | |
* Yemek yeme işleri tamamlandı. pthread_join bu çağrıyı bekliyor. | |
*/ | |
pthread_exit(NULL); | |
} | |
int | |
main() | |
{ | |
uintptr_t i; | |
/* | |
* Evre dizisi. | |
*/ | |
pthread_t diner_thread[NUMP]; | |
/* | |
* Yemek sırası için karşılıklı dışlayıcı hazırla. | |
*/ | |
pthread_mutex_init(&eat_mutex, NULL); | |
/* | |
* Çatallar için karşılıklı dışlayıcı hazırla. | |
*/ | |
for (i=0; i < NUMP; i++) | |
pthread_mutex_init(&fork_mutex[i], NULL); | |
/* | |
* Evreleri oluştur ve ilgili işleve bağla. | |
*/ | |
for (i=0; i < NUMP; i++){ | |
pthread_create(&diner_thread[i], NULL, diner, (void *) i); | |
} | |
/* | |
* Filozofların yemeklerini yemelerini bekle. | |
*/ | |
for (i=0; i < NUMP; i++) | |
pthread_join(diner_thread[i], NULL); | |
exit(EXIT_SUCCESS); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment