Professional Documents
Culture Documents
The Child Care Problem Presentation Turkish and English Presantition and Code
The Child Care Problem Presentation Turkish and English Presantition and Code
MUTEX: Turnikelere benzetebiliriz. Kart basmadan girilmez yada çıkılmaz ve o turnikeler giren çıkanı
sayar.
THREAD: İş parçacıkları olarak Türkçeleşir. Alt görev, alt iş ve küçük işler olarakta düşünelebilir.
Örneğin bir restaurantınız var ve hamburger yapmak istiyorsunuz. Asıl göreviniz Yemek pişirmek
genel olarak yemek pişiriyorsunuz bunların tümünü process olarak adlandırıyoruz. Hamburger siparişi
geldi ve hamburger pişirmeniz gerekiyor bu da bir thread’tır.
Max Hailperin bu sorunu “Operating Systems and Middleware” ders kitabı için yazdı. Çocuk bakım
merkezlerinde, devlet yönetmelikleri gereği her üç çocuk başına 1 yetişkin olması gerekir.
Puzzle: Bu kısıtlamayı kritik bir bölümde zorlayan çocuk threadları ve yetişkin threadları için kod
yazın.
Max Hailperin wrote this problem for his textbook Operating Systems and Middleware . At a child
care center, state regulations require that there is always one adult present for every three children.
Puzzle: Write code for child threads and adult threads that enforces this constraint in a critical
section.
Multiplex, her çipin bir çocuğun giriş yapmasına izin verdiği kullanılabilir çip sayısını sayar. Yetişkinler
girdikçe üç kez multiplex ağ sinyali verirler; ayrıldıkları zaman üç kez beklerler. Ancak bu çözümle ilgili
bir sorun var.
Multiplex counts the number of tokens available, where each token allows a child thread to enter. As
adults enter, they signal multiplex three times; as they leave, they wait three times. But there is a
problem with this solution.
.
Child care non-solution
Sorun, olası bir deadlock (kitlenme, çıkmaz). Çocuk bakım merkezinde üç çocuk ve iki yetişkin
olduğunu hayal edin. Multiplex ağ değeri 3’tür, bu nedenle her iki yetişkinden biri ayrılabilmelidir.
Ancak her iki yetişkin de aynı anda ayrılmaya kalkarsa, mevcut belirteçleri aralarında ve iki blok
arasında ayırabilirler.
The problem is a potential deadlock. Imagine that there are three children and two adults in the child
care center. The value of multiplex is 3, so either adult should be able to leave. But if both adults
start to leave at the same time, they might divide the available tokens between them, and both
block.
..
.
Child Care Solution
Şimdi üç bekleme işlemi bölünemez. Üç belirteç varsa, mutekste bulunan iş parçacığı üç belirteçin
tümünü alır ve çıkar. Daha az belirteç varsa, ilk iş parçacığı mutex içinde takılır ve sonraki iş
parçacıkları mutex üzerinde sıraya alınır.
Now the three wait operations are atomic. If there are three tokens available, the thread that gets
the mutex will get all three tokens and exit. If there are fewer tokens available, the first thread will
block in the mutex and subsequent threads will queue on the mutex.
.
Extended Child Care İpucusu
Children, adult , waiting and leaving keep track of the number of children, adults, children waiting to
enter, and adults waiting to leave; they are protected by mutex.
Çocuklar, gerekirse, childQueue girilmesini bekler. Yetişkinler ayrılmak için adultQueue'da bekler.
Children wait on childQueue to enter, if necessary. Adults wait on adultQueue to leave.
Extended Child-Care Solution
Bu çözüm Hailperin'in elegant çözümünden daha karmaşıktır, ancak daha önce gördüğümüz kalıpların
kombinasyonudur: Bir skor tahtası, iki queue ve "bunu sizin için yapacağım". Bu çocuk için yazılan:
This solution is more complicated than Hailperin’s elegant solution, but it is mostly a combination of
patterns we have seen before: a scoreboard, two queues, and “I’ll do it for you”. Here is the child
code:
Yetişkinler girdikçe, eğer varsa bekleyen çocuklara sinyal gönderirler. Ayrılmadan önce yeterli yetişkin
olup olmadığını kontrol ederler. Yetişkin sayısını azaltıp çıkış yaparlar. Aksi takdirde artıştan vazgeçer
ve bloklarlar. Yetişkin thread çıkış yapmayı beklerken kritik bölümdeki yetişkinlerden biri olarak sayılır
böylece ek çocuklar girebilir.
As adults enter, they signal waiting children, if any. Before they leave, they check whether there are
enough adults left. If so, they decrement adults and exit. Otherwise they increment leaving and
block. While an adult thread is waiting to leave, it counts as one of the adults in the critical section,
so additional children can enter.
1. #define __USE_GNU 1
2. #include <pthread.h>
3. #include <stdio.h>
4. #include <stdlib.h>
5. #include <unistd.h>
6. #include <semaphore.h>
7.
8. #define N_ITEMS 30
9.
10. // Tüm yetişkinleri ve tüm çocukları saklamak için buffer.
11. //Buffer, genellikle bilgisayarın belleğinde (RAM) kısa bir süre depolanan
veriler içerir.
12. int buffer_adult[N_ITEMS];
13. int buffer_child[3 * N_ITEMS];
14.
15. //Odada bulunan yetişkin ve çocukları tutan değişkenler.
16. int quantity_adult = 0, quantity_child = 0;
17.
18. // Yetişkin ve çocuklar için semafor (3 çocuk,1 yetişkin kuralı orantısı
için)
19. sem_t sem_adult;
20. sem_t sem_child;
21.
22. // Yetişkinlerin pozisyonlarını müsait olup olmadığını kontrol eden
semaforlar.
23. sem_t pos_empty_adult;
24. sem_t pos_bussy_adult;
25.
26. // Çocukların pozisyonlarını müsait olup olmadığını kontrol eden semaforlar.
27. sem_t pos_empty_child;
28. sem_t pos_bussy_child;
29.
30. //Geçici başlangıç değerleri.
31. int start_adult = 0, finish_adult = 0, finish_child = 0, finish_child = 0;
32.
33. //Odaya giren yetişkinler için fonksiyonumuz.
34. void* enter_adult(void *v) {
35.
36. int i;
37. for(i=0;i<N_ITEMS;i++){
38. sem_wait(&pos_empty_adult); //Yetişkinlerin pozisyonlarının ayarlanması
39. sem_wait(&sem_adult); //Yetişkin talebi
40.
41. //Yetişkin eklenir
42. quantity_adult += 1;
43. printf("Adult input, item = %d. just here quantity = %d\n", i, quantity_adult);
44. finish_adult = (finish_adult + 1) % N_ITEMS;
45. buffer_adult[finish_adult] = i;
46.
47. sem_post(&pos_bussy_adult); //Yetişkinin pozisyonunu 1 arttır.
48.
49. //Çocuk girişi için izin ver.(3 kez)
50. sem_post(&sem_child);
51. sem_post(&sem_child);
52. sem_post(&sem_child);
53.
54. sleep(random() % 3);
55. }
56.
57. return NULL;
58. }
59.
60. //Odaya giren çocuklar için fonksiyonumuz.
61. void* enter_child(void *v) {
62.
63. int quantity_child , i;
64. for(i=0;i< 3 * N_ITEMS;i++){
65. sem_wait(&pos_empty_child); //Çocukların pozisyonlarının ayarlanması.
66. sem_wait(&sem_child); //Çocuk talebi
67.
68. //Çocuk eklenir.
69. quantity_child += 1;
70. printf("Child input, item = %d. just here quantity = %d\n", i, quantity_child);
71. finish_child = (finish_child + 1) % (3 * N_ITEMS);
72. buffer_child[finish_child] = i;
73.
74. sem_post(&pos_bussy_child); //Çocuğun pozisyonunu 1 arttır.
75. sem_getvalue(&sem_child, &quantity_child); //Çocuk semaforunun değerini
yazdır.
76.
77. //Eğer izin verilen çocuk pozisyonu 0 ise yetişkin talep et.
78. if (quantity_child == 0){
79. sem_post(&sem_adult);
80. }
81.
82. sleep(random() % 2);
83. }
84.
85. return NULL;
86. }
87.
88. //Odadan çıkan yetişkinler için fonksiyonumuz.
89. void* exit_adult(void *v){
90.
91. int i, j;
92.
93. for (i = 0; i < N_ITEMS; i++){
94. sem_wait(&pos_bussy_adult); //Yetişkinlerin pozisyonlarının ayarlanması
95.
96. //Koşul sağlandığı sürece döndür (child>(3*adult-1))
97. while (quantity_child > 3 * (quantity_adult - 1));
98. for (j = 0; j < 3; j++){
99. sem_wait(&sem_child); //Çocuk semaforunu 1 azalt.
100. }
101.
102. //Bir yetişkini serbest bırakıyoruz.
103. start_adult = (start_adult + 1) % N_ITEMS;
104. quantity_adult -= 1;
105. printf("Leaving adult, item = %d. just here quantity = %d\n",
buffer_adult[start_adult], quantity_adult);
106.
107. sem_post(&pos_empty_adult); //Boşta olan yetişkin pozisyonunu 1
arttırıyoruz.
108.
109. //Eğer hiç yetişkin yok yada bütün yetişkinler meşgul ise yetişkin
talep et
110. if ((quantity_adult <= 0)||(3 * quantity_adult == quantity_child))
111. sem_post(&sem_adult);
112.
113. sleep(random() % 10);
114. }
115. return NULL;
116. }
117.
118.
119. //Odadan çıkan çocuklar için fonksiyonumuz.
120. void* exit_child(void *v){
121. int i, j;
122.
123. for (i = 0; i < N_ITEMS; i++){
124. sem_wait(&pos_bussy_child); //Çocuk yoğunluğunu 1 azalt
125. //Çocuğu çıkart
126. finish_child = (finish_child + 1) % (3 * N_ITEMS);
127. quantity_child -= 1;
128. printf("Leaving child, item = %d. just here quantity = %d\n",
buffer_child[finish_child], quantity_child);
129.
130. sem_post(&pos_empty_child); //Boşta olan çocuk pozisyonunu 1 arttır.
131.
132. //Koşul sağlandıkça Yetişkini bırak, çocuğu çıkart ((3*adult-
1)>child))
133. while ((quantity_adult - 1) * 3 - 1 >= quantity_child){
134. sem_wait(&pos_bussy_adult); //Meşgul yetişkin pozisyonunu 1 azalt.
135. for (j = 0; j < 3; j++){
136. sem_wait(&sem_child); //Çocuk sayısını 1 azalt.
137. }
138. start_adult = (start_adult + 1) % N_ITEMS;
139. quantity_adult -= 1;
140. printf("\n--by forcing,pulled out adult, item %d. just here quantity =
%d\n\n", buffer_adult[start_adult], quantity_adult);
141. }
142. sem_post(&sem_child); //Çocuk sayısını arttır.
143. sleep(random() % 13);
144. }
145. return NULL;
146. }
147.
148.
149. //Main fonksiyonumuz.
150. int main(){
151.
152. //Thread bildirimi
153. pthread_t thr_enter_adult, thr_enter_child, thr_exit_adult,
thr_exit_child;
154. //Tüm Semaforları başlatma
155. sem_init(&sem_child, 0, 0);
156. sem_init(&sem_adult, 0, 1);
157. sem_init(&pos_empty_adult, 0, N_ITEMS);
158. sem_init(&pos_bussy_adult, 0, 0);
159.
160. sem_init(&pos_empty_child, 0, (3 * N_ITEMS));
161. sem_init(&pos_bussy_child, 0, 0); //Fonksiyonları threadlara atama
162. pthread_create(&thr_enter_adult, NULL, enter_adult, NULL);
163. pthread_create(&thr_enter_child, NULL, enter_child, NULL);
164. pthread_create(&thr_exit_adult, NULL, exit_adult, NULL);
165. pthread_create(&thr_exit_child, NULL, exit_child, NULL);
166.
167. //Fonksiyonları threadlere joinleme
168. pthread_join(thr_enter_adult, NULL);
169. pthread_join(thr_enter_child, NULL);
170. pthread_join(thr_exit_adult, NULL);
171. pthread_join(thr_exit_child, NULL);
172.
173. //Semaforları yok et
174. sem_destroy(&sem_child);
175. sem_destroy(&sem_adult);
176. sem_destroy(&pos_bussy_adult);
177. sem_destroy(&pos_empty_adult);
178. sem_destroy(&pos_bussy_child);
179. sem_destroy(&pos_empty_child);
180.
181. return 0;