WEBVTT

00:06.160 --> 00:13.120
Evet arkadaşlar, şimdi bu ders videosunda, bazı gerçekçi örneklerin yardımıyla koşul değişkeni ve muteks

00:13.120 --> 00:15.460
kullanımını uygulayalım.

00:15.580 --> 00:21.070
Şimdi, bu örnekte, tüketici iş parçacığı olarak adlandırılan bir T1 iş parçacığım olduğunu ve üretici iş parçacığı

00:21.070 --> 00:24.940
olarak adlandırılan bir T2 iş parçacığım olduğunu görebilirsiniz.

00:25.780 --> 00:26.530
Doğru.

00:27.580 --> 00:29.800
Ve bazı veri yapılarımız var.

00:29.920 --> 00:35.620
Bu veri yapısının hiçbir şey olmadığını, sadece bazı veri öğeleri içeren bir kuyruk olduğunu

00:35.620 --> 00:43.450
ve T1 iş parçacığı ile T2 tehdidinin bu veri yapısına erişmek için birbirleriyle rekabet ettiğini varsayalım.

00:43.720 --> 00:44.440
Doğru.

00:44.650 --> 00:50.680
Şimdi, T1 tehdidi bir tüketici iş parçacığı olduğundan, bu sadece T1 iş parçacığının bu kuyruktan bir

00:50.680 --> 00:54.910
öğeyi çıkarmak ve doğru şekilde işlemek istediği anlamına gelir.

00:55.240 --> 01:03.700
T2 iş parçacığı ise bir üretici tehdididir ve bazı veriler üretir ve bu verileri bu kuyruğa iter.

01:03.730 --> 01:04.510
Doğru.

01:04.810 --> 01:11.620
Bu nedenle t1 iş parçacığı bu kuyruğu tüketirken, t2 iş parçacığı bu kuyruğa daha fazla veri besler.

01:11.650 --> 01:17.350
Bu nedenle t2 iş parçacığı üretici iş parçacığı olarak adlandırılırken, t1 iş parçacığı tüketici iş parçacığı olarak adlandırılır.

01:19.640 --> 01:21.680
Artık bir veri yapımız var.

01:21.680 --> 01:25.640
Q iş parçacıkları arasında paylaşılan bir veri kaynağıdır.

01:25.760 --> 01:30.560
Şimdi, bu veri yapısı üzerinde karşılıklı dışlama sağlamak için, bu veri yapısının

01:30.560 --> 01:36.710
kendisiyle ilişkili bir mutex nesnesine sahip olması ve ayrıca koşul değişkenine sahip olması gerekir.

01:36.740 --> 01:41.870
Koşul değişkeni, tüketici ve üretici iş parçacıklarını senkronize etmek için kullanılır.

01:42.050 --> 01:42.860
Doğru.

01:43.310 --> 01:48.680
Mutex nesnesinin ve koşul değişkenlerinin veri yapısının özellikleri olduğunu unutmayın.

01:48.710 --> 01:54.650
Koşul değişkeninin veri yapısı yerine bir iş parçacığının özelliği haline geldiği bazı küçük

01:54.650 --> 01:55.970
sapmalar olsa da.

01:55.970 --> 02:00.380
Ancak konuyu basit tutmak için bu koşulla devam edelim.

02:00.380 --> 02:02.090
Değişken ve muteksler.

02:02.090 --> 02:05.140
Her ikisi de kaynağın özellikleridir.

02:05.150 --> 02:05.960
Değil mi?

02:06.260 --> 02:14.360
Şimdi, örneği açıkladıktan sonra, T1 ve T2 iş parçacığının bu veri yapısından bir öğeyi hem ürettiği hem de tükettiği

02:14.360 --> 02:17.420
adımların üzerinden geçeceğiz.

02:17.420 --> 02:20.580
Birbirini dışlayan bir şekilde sıraya koyun.

02:20.760 --> 02:21.620
Değil mi?

02:21.630 --> 02:26.130
Ve bunun için her iki iş parçacığı da bu koşul değişkenini ve muteksi kullanır.

02:26.670 --> 02:33.690
Yani arkadaşlar, sorunumuz şu: T1 iş parçacığı kuyruktan bir öğeyi kaldırmaya çalıştığında,

02:33.690 --> 02:39.720
öğeyi engellenmeden kuyruktan başarıyla kaldırıyor.

02:39.750 --> 02:40.470
Doğru.

02:41.400 --> 02:47.880
Elbette t1 iş parçacığının kuyruğa yalnızca kuyruk iş parçacığı tarafından kullanılmadığında erişmesi gerekir.

02:47.910 --> 02:48.570
T2.

02:48.570 --> 02:49.320
Doğru.

02:50.670 --> 02:58.380
Ancak d bir tehdidi kuyruktan bir eleman çıkarmaya çalışırsa ancak kuyruk zaten boşsa, bu durumda tüketici

02:58.410 --> 03:05.690
iş parçacığımız engellenmeli ve bir üretici iş parçacığı olan D iki iş parçacığı kuyruğa yeni

03:05.730 --> 03:10.830
bir eleman itene kadar engellenmiş olarak kalmalıdır.

03:10.920 --> 03:11.730
Doğru.

03:11.730 --> 03:15.270
İşte çözmeye çalıştığımız sorun ifadesi budur.

03:15.270 --> 03:19.860
Ve daha ünlü olarak, bu problem ifadesine üretici Tüketici problemi denir.

03:20.010 --> 03:25.830
Dolayısıyla sorun ifadesi, T1 iş parçacığının kuyruktan bir öğeyi kaldırmaya çalışması ve kuyruğun

03:25.830 --> 03:30.500
zaten boş durumda olması halinde engellenmesi gerektiği konusunda açıktır.

03:30.510 --> 03:31.140
Doğru.

03:31.140 --> 03:37.470
Ve tüketici iş parçacığının, üretici iş parçacığı bir öğe üretip kuyruğa itene kadar bloke

03:37.470 --> 03:39.180
kalması beklenir.

03:39.210 --> 03:40.050
Doğru.

03:40.590 --> 03:47.340
Şimdi bu mantığı uygulamak için koşul değişkenleri muteksleri ve yüklemlerin nasıl bir araya gelebileceğini

03:47.340 --> 03:49.350
adım adım görelim.

03:50.140 --> 03:52.900
Şimdi yüklem, karşılaştığınız yeni bir terimdir.

03:52.900 --> 03:56.260
Yüklemin tam olarak ne olduğunu açıklayacağım.

03:57.790 --> 04:02.080
Öncelikle tüketici konusuyla başlayalım.

04:02.080 --> 04:02.830
Değil mi?

04:03.100 --> 04:08.830
Dolayısıyla, tüketici iş parçacığının yapması gereken ilk şey, bir kuyruk olan paylaşılan kaynak üzerinde

04:08.830 --> 04:10.780
bir kilit elde etmektir, değil mi?

04:10.810 --> 04:16.930
Unutmayın, kuyruk paylaşılan bir kaynaktır ve her iki iş parçacığı da bu paylaşılan kaynağa erişim

04:16.930 --> 04:20.380
talep ederken karşılıklı dışlama kuralına uymalıdır.

04:20.500 --> 04:26.530
Bu nedenle, tüketici iş parçacığının bu kuyruk üzerinde herhangi bir işlem gerçekleştirebilmesi için öncelikle bu kuyruğa kilitlenmesi

04:26.530 --> 04:27.400
gerekir.

04:28.170 --> 04:30.450
Şimdi de T1 ipliğini varsayalım.

04:31.720 --> 04:34.810
Bu kuyruk üzerinde kilit elde edebilir.

04:34.840 --> 04:40.420
T1 iş parçacığının yapacağı bir sonraki şey bu kuyruktan bir öğe tüketmektir.

04:40.450 --> 04:41.230
Doğru.

04:41.230 --> 04:47.710
Ve t1 iş parçacığı bu kuyruktaki öğeyi yalnızca kuyruk boş olmadığında tüketebilmelidir.

04:47.920 --> 04:54.670
Yani basitçe, kuyruk boşsa tüketici iş parçacığının engellenmesi gerektiği anlamına gelir.

04:54.940 --> 04:55.720
Doğru.

04:56.140 --> 04:58.840
Bunu S2 numaralı adımda görebilirsiniz.

04:58.840 --> 05:02.250
Tüketici iş parçacığı kaynağın durumunu test ediyor.

05:02.260 --> 05:04.860
Bu, kuyruğun boş olup olmadığıdır.

05:04.870 --> 05:11.440
Dolayısıyla, kaynağın durumunu kontrol etmek anlamına gelen S2 adımını özel olarak gerçekleştirmek.

05:11.470 --> 05:17.980
İş parçacığı tarafından kaynağın durumunu kontrol etmek için kullanılan koşul teknik olarak yüklem olarak adlandırılır.

05:18.100 --> 05:20.920
Yani bu koşula yüklem denir.

05:22.730 --> 05:29.330
Yani iş parçacığı senkronizasyonu dünyasında kullanılan teknik bir terimdir ve yüklem, iş parçacığının

05:29.330 --> 05:33.940
kaynağın durumunu test ettiği koşulu temsil eder.

05:33.950 --> 05:42.680
Dolayısıyla, S2 numaralı adımın tüketici iş parçacığı tarafından özel olarak gerçekleştirilmesi için S1 adımı gereklidir, yani muteksin

05:42.680 --> 05:44.430
kilitlenmesi gerekir.

05:44.450 --> 05:49.000
Şimdi bu muteksin neden gerekli olduğunu anlıyorsunuz, değil mi?

05:49.010 --> 05:55.730
Böylece iş parçacığı kaynağın durumunu kontrol ederken iş parçacığı kaynağın durumunu özel olarak kontrol

05:55.730 --> 05:56.900
edebilir.

05:56.930 --> 06:01.520
Sürecin başka hiçbir iş parçacığı kaynağın durumunu değiştirmemelidir.

06:01.520 --> 06:06.110
İşte bu nedenle adım numarasında muteks kilitleme gereklidir.

06:06.110 --> 06:13.210
S1 ve yüklem, iş parçacığına beklemesi gerekip gerekmediğini söyleyen bir koşuldur.

06:13.220 --> 06:13.970
Doğru.

06:13.970 --> 06:21.140
Bu örnekte, S2 numaralı adım koşulu test etmektedir ve teknik olarak bu koşul yüklem olarak adlandırılmaktadır.

06:23.100 --> 06:29.340
Şimdi, tüketici iş parçacığının kuyruğu boş olarak bulduğunu, yani tüketici iş parçacığının tüketecek

06:29.340 --> 06:36.030
hiçbir şeyi olmadığını varsayarsak, tüketici iş parçacığının engellenmesi gerekir ve üçüncü adımda bir API

06:36.030 --> 06:39.630
p iş parçacığı koşulunu çağırmamızın nedeni budur.

06:39.630 --> 06:46.050
Problem ifadesi uyarınca tüketici iş parçacığını bloke etmek için bekleyin, üretici iş parçacığı öğeyi

06:46.050 --> 06:51.360
boş kuyruğa itene kadar tüketici iş parçacığımızın bloke kalmasını istiyoruz.

06:51.690 --> 06:57.090
Yani burada, bekleme koşulu doğruysa, yani kuyruk boşsa.

06:57.120 --> 07:02.310
Tüketici iş parçacıklarımız üçüncü adımda koşul değişkenini kullanarak kendini bloke eder.

07:02.460 --> 07:03.270
Doğru.

07:03.900 --> 07:09.480
Şimdi üçüncü adımda, tüketici iş parçacığı engellenmiş durumda, değil mi?

07:09.990 --> 07:15.600
Yani tüketici iş parçacığı şimdi üretici iş parçacığının bir öğe üretmesini ve kuyruğa itmesini

07:15.600 --> 07:16.620
bekliyor.

07:16.980 --> 07:21.570
Yani bu basitçe, üretici ipliğinin artık resme gireceği anlamına geliyor.

07:23.560 --> 07:26.560
Şimdi üretici iş parçacığının kuyruğa bir öğe itmesi gerekiyor.

07:26.590 --> 07:31.660
Bu, üretici iş parçacığının paylaşılan bir kaynak üzerinde yazma işlemi gerçekleştirdiği anlamına gelir.

07:31.660 --> 07:32.440
Değil mi?

07:32.470 --> 07:38.740
Bu da basitçe, üretici iş parçacığının da paylaşılan kaynak kuyruğuna karşılıklı olarak özel bir erişime ihtiyaç duyduğu anlamına

07:38.770 --> 07:39.370
gelir.

07:39.370 --> 07:44.140
Ve bu nedenle üretici iş parçacığı muteksin kilitlenmesi ile başlar.

07:44.140 --> 07:44.950
Doğru.

07:46.290 --> 07:50.700
Tüketici iş parçacığının üçüncü adımda blok durumunda olduğunu unutmayın.

07:50.700 --> 07:57.180
Bu muteksin perde arkasında kilidinin açıldığını zaten biliyoruz ve bu muteksin kilidi açıldığı

07:57.180 --> 08:04.290
için üretici iş parçacığı artık altıncı adımda bu muteks üzerindeki kilidi ele geçirebilir.

08:04.860 --> 08:10.530
Şimdi bir üretici iş parçacığı kuyruğun dolu olup olmadığını test edecektir.

08:10.560 --> 08:18.990
Doğru, bu yedi numaralı adımda, üretici iş parçacığı bir öğe üretebilir ve onu kuyruğa itebilir.

08:19.170 --> 08:26.420
Yani bu özel eylem, paylaşılan bir kaynak üzerinde gerçekleştirilen bir yazma işlemini temsil ediyor, değil mi?

08:26.430 --> 08:33.660
Başka bir deyişle, burası kritik bölümdür ve üretici iş parçacığı öğeyi başarılı bir şekilde kuyruğa ittikten sonra,

08:33.660 --> 08:40.080
üretici iş parçacığının tüketici iş parçacığına sinyal göndererek tüketici iş parçacığına "hey, tüketici

08:40.350 --> 08:45.990
iş parçacığı, kuyruğa bir öğe yerleştirdim" diye bildirdiğini görebilirsiniz.

08:45.990 --> 08:49.170
İnfazına devam edebilirsin, değil mi?

08:49.940 --> 08:55.130
Böylece sekiz numaralı adım üretici iş parçacığı tarafından yürütüldükten sonra.

08:56.840 --> 08:59.920
Bu koşul değişkenine bir sinyal gönderilecektir.

08:59.930 --> 09:00.740
Doğru.

09:01.130 --> 09:05.980
Dolayısıyla T2 tehdidi, yani üretici tehdidi, adım numarasındaki kaynak durumunu kontrol eder.

09:06.050 --> 09:14.480
S7 S6 numaralı adımda ayrıcalık sözü verirken yeni elemanı üretir ve kuyruğa

09:14.480 --> 09:15.200
alır.

09:16.010 --> 09:23.330
Ardından üretici tehdit S8 numaralı adımda tüketici tehdide sinyal gönderir ve S9 numaralı

09:23.330 --> 09:27.650
adımda üretici tehdit muteksin kilidini açar.

09:27.680 --> 09:30.590
Tamam, bu API kilidini açmak.

09:31.850 --> 09:39.650
Sekiz numaralı adımdan hemen sonra ve dokuz numaralı adımdan önce, tüketici iş parçacığının engellenmiş durumdan yürütmeye

09:39.650 --> 09:45.650
hazır duruma geçtiğini, ancak tüketici iş parçacığının dört numaralı adımı yalnızca üretici iş

09:45.890 --> 09:50.770
parçacığı muteksin kilidini başarıyla açtığında yürüteceğini unutmayın.

09:50.780 --> 09:52.910
Bu dokuzuncu adım.

09:53.270 --> 09:59.030
Yalnızca dokuz numaralı adımdan sonra, tüketici iş parçacığı gerçekten yürütülmeye başlar.

09:59.540 --> 10:07.430
Dolayısıyla, dördüncü adımda, tüketici iş parçacığı yürütmeye devam eder etmez, bu muteks üzerindeki kilit işletim

10:07.460 --> 10:12.170
sistemi tarafından dahili olarak tüketici iş parçacığına verilir.

10:12.440 --> 10:13.220
Doğru.

10:13.220 --> 10:15.110
Ve bu nedenle sadece.

10:15.110 --> 10:18.530
Tüketici iş parçacığı bu kuyruk üzerinde işlem gerçekleştirebilir.

10:18.560 --> 10:22.160
Yani, artık bu kuyruktan bir öğe tüketebilir.

10:22.190 --> 10:28.110
Dolayısıyla S4 numaralı adım, tüketici iş parçacığının uyandırıldığında yürüttüğü kritik bölümdür.

10:28.130 --> 10:28.970
Doğru.

10:29.300 --> 10:35.630
Ve son olarak, tüketici iş parçacığı kuyruktan bir öğe tüketirken işi bittiğinde, tüketici iş parçacığı

10:35.630 --> 10:38.200
muteksin kilidini açabilir.

10:38.210 --> 10:39.020
Değil mi?

10:39.440 --> 10:44.510
Bu yüzden beşinci adımda, işiniz bittiğinde paylaşılan verilerin kilidini açıkça açın.

10:45.080 --> 10:51.980
Peki tüm bu hikayede, kritik bölümü temsil eden adımlar nelerdir diye soracak olursam, basitçe tanımdan

10:51.980 --> 10:58.040
yola çıkarak kritik bölüm, paylaşılan kaynağa eriştiğimiz kod parçasıdır.

10:58.190 --> 11:03.960
Dolayısıyla, üretici tarafındaki bu belirli kod bölgesi kritik bölümdür.

11:03.960 --> 11:10.530
Ve tüketici tarafındaki bu belirli kod bölgesi kritik bölüm, değil mi?

11:11.340 --> 11:18.780
Tüm bu hikayeyi analiz ederseniz, herhangi bir zamanda tüketici ve üretici ipliğinin karşılıklı dışlama

11:18.810 --> 11:21.560
ilkesine uyduğunu göreceksiniz.

11:21.570 --> 11:22.350
Değil mi?

11:22.830 --> 11:30.180
Bir kez daha yinelemek gerekirse, bu muteksin rolü, rekabet halindeki iş parçacıklarının paylaşılan kaynağa karşılıklı

11:30.180 --> 11:36.450
olarak özel erişime sahip olmalarını sağlamaktır; bu koşul değişkeninin rolü ise kaynak için rekabet

11:36.450 --> 11:40.820
eden iş parçacıkları arasında koordinasyona izin vermektir.

11:40.830 --> 11:41.520
Doğru.

11:41.550 --> 11:48.000
Bu koşul değişkeni sayesinde tüketici iş parçacığı kendini bloke edebilmiş ve üretici iş parçacığı

11:48.000 --> 11:51.420
koşul değişkenine sinyal gönderebilmiştir.

11:51.420 --> 11:52.230
Doğru.

11:52.990 --> 12:00.430
Ayrıca şimdi S1'den S9'a kadar olan adım sayısını tamamladık ve eksik adım sayısı

12:00.460 --> 12:03.970
olan S2, S4 ve S7'yi tamamladık.

12:04.870 --> 12:10.360
Şu andan itibaren, iş parçacığı senkronizasyonunun en zor kısmı olan koşul değişkeni ve mutekslerle

12:10.360 --> 12:12.460
çalışmakla uğraşıyorsunuz.

12:12.490 --> 12:13.180
Doğru.

12:13.210 --> 12:20.230
Muteksleri ve koşul değişkenlerini nasıl kullanacağınızı net bir şekilde anladıktan sonra, iş parçacığı senkronizasyonu

12:20.230 --> 12:28.570
için kullanılan monitor, semaforlar gibi daha karmaşık ve sofistike veri yapılarını uygulayabileceksiniz.

12:28.840 --> 12:35.290
Şimdi bu kod parçalarında, bir sonraki ders videosunda tartışacağımız bir iyileştirme

12:35.290 --> 12:36.580
kapsamımız var.
