Challenge 6
Forum kuralları
Forum kurallarını okuyup, uyunuz!
Forum kurallarını okuyup, uyunuz!
Challenge 6
Bir sonraki challenge'da deadlock'tan bahsedeceğimizi ifade etmiştim. Sadettin'in Challange 5'de bu konuya atıf yapmasını da fırsat bilerek yeni bir challange ile karşınızdayım.
Yazdığınız programlarınızda thread kullanıyorsanız eğer başınıza bazı sıkıntılı işler gelmiş olabilir. Örneğin; uygulamanızda birden fazla thread aktif olarak çalışıyor ve siz uygulamanızın ana formunun OnClose olay yöneticinde kapanış esnasında ilgili thread'lerin bitmesini beklemek istiyorsunuz ve bu bekleme işlemi bir türlü sonlanmıyor; siz de IDE'den çalıştırıyor iseniz programınızı Ctrl+F2 ile kırıyor musunuz ya da Görev Yöneticisi üzerinden programı sonlandırıyor musunuz ?
Yada programınız daha kullanıcı dostu olsun diye sağa sola serpiştirdiğiniz thread'leriniz uygulamanızın ana thread'ini bloke mi ediyor ? Ana formunuz hiç yanıt vermez duruma mı geliyor ?
Eğer yukarıdaki sorulardan bir yada birden fazlasına evet dedi iseniz; kuvvetle muhtemeldir ki uygulamanızda deadlock'lar oluşuyor. Sizlere bunların nasıl oluştuğunu ve nasıl bertaraf edileceğini izah etmeye gayret edeceğim ama her zaman olduğu gibi önce sizlerin görüşlerini ve katılımını rica ediyorum.
Lütfen bu paylaşımları birer test olarak görmeyin ve doğru yada yanlış fikirleriniz ile katılımda bulunun. Sitenin müdavimlerinin dahi; challenge'lara katılmıyor olmasının bir nedeni var ise bunu da bilmek isterim gerçekten. Bilmemek ayıp değildir, hepimiz herşeyi bilemeyiz zaten; ama araştırmamak, kendini geliştirmemek, kendinizi geliştirebilmenize imkan sağlamaya çalışanlara kayıtsaz kalmak; işte o bence ayıptır.
Herneyse; sorularımıza geçelim müsaadeye binaen;
1.Soru: Uygulamanız içinde bir thread'iniz olacak ve bu thread ile ana thread birbirlerini bloke edecekler. Nasıl ?
2.Soru: Uygulamanızın ana thread'i bloklanmadan 2 ayrı thread'in birbirini bloklamasını sağlayabilir misiniz. Nasıl ?
3.Soru: Uygulamanızın kapanışı esnasında yada herhangi bir an diliminde; uygulamanız içinde yaşayan thread'lerin; durumlarını sorgulayabilir ve bloke olup olmadıklarını kontrol edebilir misiniz. Nasıl ?
Not: İnananlar için paylaşmak; Allah'ın size nasip ettiği ilmin zekatıdır.
Yazdığınız programlarınızda thread kullanıyorsanız eğer başınıza bazı sıkıntılı işler gelmiş olabilir. Örneğin; uygulamanızda birden fazla thread aktif olarak çalışıyor ve siz uygulamanızın ana formunun OnClose olay yöneticinde kapanış esnasında ilgili thread'lerin bitmesini beklemek istiyorsunuz ve bu bekleme işlemi bir türlü sonlanmıyor; siz de IDE'den çalıştırıyor iseniz programınızı Ctrl+F2 ile kırıyor musunuz ya da Görev Yöneticisi üzerinden programı sonlandırıyor musunuz ?
Yada programınız daha kullanıcı dostu olsun diye sağa sola serpiştirdiğiniz thread'leriniz uygulamanızın ana thread'ini bloke mi ediyor ? Ana formunuz hiç yanıt vermez duruma mı geliyor ?
Eğer yukarıdaki sorulardan bir yada birden fazlasına evet dedi iseniz; kuvvetle muhtemeldir ki uygulamanızda deadlock'lar oluşuyor. Sizlere bunların nasıl oluştuğunu ve nasıl bertaraf edileceğini izah etmeye gayret edeceğim ama her zaman olduğu gibi önce sizlerin görüşlerini ve katılımını rica ediyorum.
Lütfen bu paylaşımları birer test olarak görmeyin ve doğru yada yanlış fikirleriniz ile katılımda bulunun. Sitenin müdavimlerinin dahi; challenge'lara katılmıyor olmasının bir nedeni var ise bunu da bilmek isterim gerçekten. Bilmemek ayıp değildir, hepimiz herşeyi bilemeyiz zaten; ama araştırmamak, kendini geliştirmemek, kendinizi geliştirebilmenize imkan sağlamaya çalışanlara kayıtsaz kalmak; işte o bence ayıptır.
Herneyse; sorularımıza geçelim müsaadeye binaen;
1.Soru: Uygulamanız içinde bir thread'iniz olacak ve bu thread ile ana thread birbirlerini bloke edecekler. Nasıl ?
2.Soru: Uygulamanızın ana thread'i bloklanmadan 2 ayrı thread'in birbirini bloklamasını sağlayabilir misiniz. Nasıl ?
3.Soru: Uygulamanızın kapanışı esnasında yada herhangi bir an diliminde; uygulamanız içinde yaşayan thread'lerin; durumlarını sorgulayabilir ve bloke olup olmadıklarını kontrol edebilir misiniz. Nasıl ?
Not: İnananlar için paylaşmak; Allah'ın size nasip ettiği ilmin zekatıdır.
Re: Challenge 6
Hiçkimse mi threading kullanmıyor ya da herkes mi doğru kullanıyor threadleri ?
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim:
Re: Challenge 6
Deadlock (Temsili)
thelvaci yazdı: 1.Soru: Uygulamanız içinde bir thread'iniz olacak ve bu thread ile ana thread birbirlerini bloke edecekler. Nasıl ?
Soruyu cok iyi anlamadim. normalda olmasini istemeyecegimiz bir durumu kendimiz mi olusturmamiz lazim ?
Boyle bir sey istiyorsam ana thread icinde ikinci threadin yapmasi gereken bir isi beklerken ikinci threadin da bu isi yapmasi icin ana thread icinde ki bir islemin meydana gelmesini beklerdim.
bu durumda iki threadde birbirini bekleyeceklerinden aklima sunay akinin su misralari gelirdi.
iki rayi gibiyiz bir tren yolunun
yakin olmasi neyi degistirir son istasyonun
thelvaci yazdı: 2.Soru: Uygulamanızın ana thread'i bloklanmadan 2 ayrı thread'in birbirini bloklamasını sağlayabilir misiniz. Nasıl ?
a seceneginde ki cevapla ayni sekilde.
ben genelde threadlere ThreadBittiMi diye bir degisken koyup form close olayinda bu degiskenin degerini kontrol ediyorum.thelvaci yazdı: 3.Soru: Uygulamanızın kapanışı esnasında yada herhangi bir an diliminde; uygulamanız içinde yaşayan thread'lerin; durumlarını sorgulayabilir ve bloke olup olmadıklarını kontrol edebilir misiniz. Nasıl ?
belirli bir sure sonra thread sonlanmadiysa gozumu karartip threadi sonlandirip akabinde de programi sonlandiriyorum.
Re: Challenge 6
Teşekkür ederim yanıtına Sadettinim. Evet senin de ifade ettiğin gibi normalde olmasını istemediğimiz bir senaryoyu istiyoruz. Doğru söylüyorsun iki thread'in birbirini beklemesi ve deadlock'a ulaşmak hedefimiz. Böylece yapmamamız gerekenleri göstermiş olacak bu senaryo. Evet; ama nasıl kısmını da yanıtlamanızı istiyorum. Hangi yöntemler ile birbirini bloklayan ve deadlock oluşturan sonuçları görebiliriz. Bunu paylaşmanızı istiyorum esasen.
Üçüncü sorumda ise bir değişkenin durumunu kontrol ederek işlem yapamazsın. Kontrol edeceğin thread'ler bloke durumda çünkü Ayrıca thread'ler uzun zaman bloke olmuş ise gözümü karartırım thread'in kafasına kabak atar öldürürüm demek de olmaz İşimiz onların bloklanmamasını sağlamak.
İşte bu neden ile bu challange'ı açtım; çok iyi biliyorum çünkü pek çok arkadaşımız senin söylediğin gibi yapıyor; ama yapılması gereken bu değil. Bu nedenle sorumu yineliyorum; thread'leri sorduğum kriterler ile bloke edebilir misiniz ?
Nasıl bloke olduklarını ve nedenlerini gözlemleme de bir faydamız olabilir ise eğer; bu durumda bloke olmayan yada daha zor bloke olan thread'ler yazabiliriz ve programımız daha güvenli olur.
Üçüncü sorumun yanıtını veren bir API grubu var diyerek de bir ipucu vermiş olayım
Üçüncü sorumda ise bir değişkenin durumunu kontrol ederek işlem yapamazsın. Kontrol edeceğin thread'ler bloke durumda çünkü Ayrıca thread'ler uzun zaman bloke olmuş ise gözümü karartırım thread'in kafasına kabak atar öldürürüm demek de olmaz İşimiz onların bloklanmamasını sağlamak.
İşte bu neden ile bu challange'ı açtım; çok iyi biliyorum çünkü pek çok arkadaşımız senin söylediğin gibi yapıyor; ama yapılması gereken bu değil. Bu nedenle sorumu yineliyorum; thread'leri sorduğum kriterler ile bloke edebilir misiniz ?
Nasıl bloke olduklarını ve nedenlerini gözlemleme de bir faydamız olabilir ise eğer; bu durumda bloke olmayan yada daha zor bloke olan thread'ler yazabiliriz ve programımız daha güvenli olur.
Üçüncü sorumun yanıtını veren bir API grubu var diyerek de bir ipucu vermiş olayım
Re: Challenge 6
Criticalsection'a enter yapip leave yapmadan ikinci thread'i kilitleyebilecegimi saniyorum. Ana thread'da waitfor kullanip ara thread'da ise criticalsection ile bloke ettik mi, ana thread sen gelmez oldun sarkisinin sözlerini yazmaya baslar
Yada pool kullanip tüm threadleri bir execute prosedürüne yönlendirip execute prosedürünün girisini kilitledik mi tüm pool icindeki worker'lar kilitlenmis olurlar.
Yada pool kullanip tüm threadleri bir execute prosedürüne yönlendirip execute prosedürünün girisini kilitledik mi tüm pool icindeki worker'lar kilitlenmis olurlar.
kıdemsiz üye
Re: Challenge 6
Basit de olsa örnekleri görelim Daha sonra bu başlık altındaki örnekleri arzu ederseniz tartışırız da. İki kilitleme yöntemini ben ipucu olarak vereyim madem;ikra yazdı:Criticalsection'a enter yapip leave yapmadan ikinci thread'i kilitleyebilecegimi saniyorum. Ana thread'da waitfor kullanip ara thread'da ise criticalsection ile bloke ettik mi, ana thread sen gelmez oldun sarkisinin sözlerini yazmaya baslar
Yada pool kullanip tüm threadleri bir execute prosedürüne yönlendirip execute prosedürünün girisini kilitledik mi tüm pool icindeki worker'lar kilitlenmis olurlar.
Bunlar bizim en sık yaptığımız kilitlenmelerin başrol oyuncuları;
1- TThread.Synchronize
2- SendMessage
Bunlar ile de kilitlenme işlemini gözlemleyebilir misiniz ?
Re: Challenge 6
Unutmadan bir tane daha vereyim; GetWindowText
Bu kilitlenmeleri bilfiil test edip gözlemleyebilir misiniz ?
Bu kilitlenmeleri bilfiil test edip gözlemleyebilir misiniz ?
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim:
Re: Challenge 6
Abi soyle bir thread olsa
ana threadde soyle olsa
edit1.text = deadlock olursa iki threadi de kilitlemis oluruz. sonsuza kadar bekler dururlar
Kod: Tümünü seç
TThreadDeneme = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
Sonuc:Boolean;
end;
procedure TThreadDeneme.Execute;
var
deger:string;
begin
sonuc := False;
Synchronize(
procedure
begin
deger := Form26.edit1.text;
end
);
if deger = 'deadlock' then
begin
while deger = 'deadlock' do
begin
Synchronize(
procedure
begin
deger := Form26.edit1.text;
end
);
Sleep(1);
end;
end;
sonuc := True;
end;
ana threadde soyle olsa
Kod: Tümünü seç
procedure TForm26.Button1Click(Sender: TObject);
var
myThread:TThreadDeneme;
begin
myThread := TThreadDeneme.Create(True);
myThread.Start;
while myThread.sonuc = false do
Application.ProcessMessages;
ShowMessage('bitti');
end;
edit1.text = deadlock olursa iki threadi de kilitlemis oluruz. sonsuza kadar bekler dururlar
Re: Challenge 6
Ama ana thread hâla responsive durumda Öyle bir şey yapın ki ana thread'de gümlesin. Hiçbirşeye cevap veremez hale gelsin.
Re: Challenge 6
Örneğin:
Kod: Tümünü seç
unit uThreadBlockingChallange;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
DummyThread,
DummyThread2 : TThread;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure L(const AMessage : String);
begin
form1.Memo1.Lines.Add( AMessage );
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
DummyThread :=
TThread.CreateAnonymousThread(
procedure
begin
TThread.CurrentThread.FreeOnTerminate := false;
Sleep(1000);
// Ana thread context'inde bir metod çağrımı yapalım.
TThread.Synchronize(
nil,
procedure
begin
L('Ana threade benden selam olsun...');
end
);
end
);
DummyThread.Start;
// Thread'in bitmesini bekleyelim
WaitForSingleObject(DummyThread.Handle, INFINITE);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
DummyThread2 :=
TThread.CreateAnonymousThread(
procedure
begin
TThread.CurrentThread.FreeOnTerminate := false;
Sleep(1000);
// Ana thread'e mesaj gönderelim.
SendMessage(Application.MainForm.Handle, WM_NULL, 0, 0);
end
);
DummyThread2.Start;
// Thread'in bitmesini bekleyelim
WaitForSingleObject(DummyThread2.Handle, INFINITE);
end;
end.
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim:
Re: Challenge 6
thelvaci yazdı:Ama ana thread hâla responsive durumda Öyle bir şey yapın ki ana thread'de gümlesin. Hiçbirşeye cevap veremez hale gelsin.
abi basit , dongudeki app.ProcessMessages ' i kaldirdik mi tamamdir
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim:
Re: Challenge 6
adam bosuna yazmamis Don’t use the TThread.Synchronize procedure diye
Don’t use the TThread.Synchronize procedure. Recent versions of Delphi include TThread.Queue, which is asynchronous, and so avoids this deadlock.
https://marc.durdin.net/2012/08/waitfor ... er-use-it/
Don’t use the TThread.Synchronize procedure. Recent versions of Delphi include TThread.Queue, which is asynchronous, and so avoids this deadlock.
https://marc.durdin.net/2012/08/waitfor ... er-use-it/
Re: Challenge 6
Evet, en sık karşılaşılan hatalardan birisidir. Gerçekten emin isek TThread.Synchronize çağrımını yaptığımız thread'in ana thread tarafından beklenmediğine o durumda kullanabiliriz, bir sakıncası yok. Ancak; ana thread'in herhangi bir thread'i yada o thread içinde kapalı konuma geçmiş(nonsignaled) bir kernel nesnesini beklediği bir durum var ise ve o thread'de ana thread'e TThread.Synchronize ile ulaşıyorsa; o zaman Deadlock ile karşılaşırız. Kısacası, ortak kaynakların birbirlerini bekledikleri kimsenin bir adım ilerleyemediği senaryodur ve maalesef sıklıkla karşılaşılır. O sebep ile bu konuyu açma ihtiyacı hissettim. TThread.Synchronize en bariz örneklerden birisidir. Ancak; SendMessage'da ikinci en sık deadlock senaryolarından birisidir. SendMessage çağrımı mesajın alındığı pencerenin kuyruk yöneticisi tarafından direkt işletilir ve geriye döner. Yani SendMessage çağrımını yapan thread çağrım bitene kadar bloklanacaktır. Mesajın ulaşmaya çalıştığı thread'de bloking durumda ise ve işin kötüsü mesajı göndereni bekliyor ise bu durumda karşımıza yine Deadlock çıkar.
O yüzden multithreading zor olarak algılanır ve tasarıma dikkat edilmez ise gerçekten de zor hâle kolaylıkla gelebilir. İşin özünde yatan; kaynakların efektif kullanımını sağlamak ve aynı anda aynı kaynağa erişimleri organize etmektir. Esas amaç, bir kaynaktan yararlanmak için bekleyen unsurların adil organizasyonunu sağlayabilmektir. Neden adil ifadesine vurguda bulundum ? Bunun sebebi Challange 5'de Sadettin'in bahsini açtığı starvation (açlık) kavramına vurgu yapmak için.
Bir kaynağı paylaşması gereken unsurların paylaşılan kaynağı adil kullanmasını sağlamazsanız; bekleyen unsurlardan bir yada bir kaçı kaynağı uzun süre kullanamayacaktır. Bu duruma starvation açlık adı verilir. Örneğin; elektrik faturanızı ödemek için vezne kuyruğunda bekliyorsunuz ve veznedarın akrabaları, arkadaşları, diğer veznedarların arkadaşları vs. sürekli gelip sizin önünüze geçiyor ve durum sürekli bu şekilde işliyor. Bu durumda siz asla faturanızı yatıramıyorsunuz. İşte buna kaynağı bekleyen unsurun açlığı adı verilir. İşletim sistemi de thread'ler arasındaki açlığı engellemek için çeşitli mekanizmalara sahiptir. Örneğin işletim sistemi üzerinde çalışan 5 tane realtime thread, 4 tane high priority thread ve 1 tanede gariban low priority thread olsun. İşletim sistemi önce realtime önceliğe sahip olan thread'leri işleyip bitirmeye çalışacaktır; ardından high ve en sonda gariban thread'e sıra gelecektir. Ancak tam gariban thread'e sıra gelecekken yine bir realtime thread gelirse ne olacaktır. Bu durumda bizim gariban thread açlıktan geberecekmidir Hayır elbette öyle olmayacaktır, bu gibi bir durumun oluşmaya başladığını anlayan işletim sistemi ilgili thread'in önceliğini bir müddetliğine yükseltecek ve onun da gönlünü alacak sonra önceliğini tekrar eski durumuna geri çekecektir. Bu işleme priority boosting demişler.
Kısacası threading esasen kolay bir konudur, yeterki kısıtlı kaynaklarınızın olduğunu bilin ve kaynakları adil bir şekilde yönetmenize yardımcı olması için hizmetinize sunulan senkronizasyon nesnenerini düzgün bir şekilde kullanın. O zaman çok ciddi sorunlar ile karşılaşma ihtimaliniz epey bir azalır.
Neyse konumuz açlık değil elbette, ama aklıma gelince bir iki kelam edeyim dedim. Yukarıda gönderdiğim örneklerdeki deadlockları çözmek için ilkinde; TThread.Synchronize yerine TThread.Queue yazabilirsiniz. Bu metod; uygulamanızın ana thread'inin bloklu olup olmadığı ile ilgilenmez; yapacağı işler kuyruğunun en altına bir işi atıp geri döner. Ana thread'iniz yaptığı işi bitirdiğinde bir sonraki işi kuyruktan alıp işleyebilir ve deadlock'a müsaade edilmemiş olur.
İkinci örnekte; SendMessage yerine PostMessage kullanabilirsiniz. Dediğim gibi SendMessage blocking bir API'dir ve karşıda mesajı alacak olan thread'in mesajı işleyip geriye dönmesini bekler. Oysaki PostMessage tıpkı TThread.Queue gibi davranır ve ilgili mesajın hedef thread'in mesaj kuyruğunun en sonuna ekler. İlla SendMessage çağrımı yapmam gerekiyor diyorsanız; SendMessage yerine SendMessageTimeOut'u kullanmanızı öneririm.
Ayrıca en son olarak belirttiğim GetWindowText API'si gibi başka API'lerde vardır ve kullandığınız API'lerin msdn açıklamalarını okumak için zaman ayırmanızın önemli olduğunu söyleyebilirim. GetWindowText API'si de yukarıdaki örnekte deadlock'a yol açacaktır çünkü iç yapısında hedef pencerenin başlık bilgisini elde edebilmek için hedef pencereye SendMessage API'si ile WM_GETTEXT mesajını iletir ve yanıtını bekler.
Bu ve buna benzer Deadlock senaryolarını çoğaltabilirsiniz. Bu nedenle, birden fazla thread ile işlem yapacak ve ortak kaynaklara müracaat edecekseniz; gidin bir bardak kahve alın ve önce bir kağıt üzerinde hangi thread hangi kaynağa ne zaman ve nasıl ulaşacak diye yazın/çizin. Ardından kodlamaya geçin.
Şimdi; bu bilgilerin ışığında artık bir yada birden fazla thread'in birbirlerini beklemelerinden kaynaklanan Deadlock senaryolarını oluşturabileceğinize göre; 3ncü soru hakkında ne düşünüyorsunuz ?
Deadlock durumda olan, yada sonsuz bekleme durumunda olan thread'lerimizi nasıl tespit edeceğiz ?
O yüzden multithreading zor olarak algılanır ve tasarıma dikkat edilmez ise gerçekten de zor hâle kolaylıkla gelebilir. İşin özünde yatan; kaynakların efektif kullanımını sağlamak ve aynı anda aynı kaynağa erişimleri organize etmektir. Esas amaç, bir kaynaktan yararlanmak için bekleyen unsurların adil organizasyonunu sağlayabilmektir. Neden adil ifadesine vurguda bulundum ? Bunun sebebi Challange 5'de Sadettin'in bahsini açtığı starvation (açlık) kavramına vurgu yapmak için.
Bir kaynağı paylaşması gereken unsurların paylaşılan kaynağı adil kullanmasını sağlamazsanız; bekleyen unsurlardan bir yada bir kaçı kaynağı uzun süre kullanamayacaktır. Bu duruma starvation açlık adı verilir. Örneğin; elektrik faturanızı ödemek için vezne kuyruğunda bekliyorsunuz ve veznedarın akrabaları, arkadaşları, diğer veznedarların arkadaşları vs. sürekli gelip sizin önünüze geçiyor ve durum sürekli bu şekilde işliyor. Bu durumda siz asla faturanızı yatıramıyorsunuz. İşte buna kaynağı bekleyen unsurun açlığı adı verilir. İşletim sistemi de thread'ler arasındaki açlığı engellemek için çeşitli mekanizmalara sahiptir. Örneğin işletim sistemi üzerinde çalışan 5 tane realtime thread, 4 tane high priority thread ve 1 tanede gariban low priority thread olsun. İşletim sistemi önce realtime önceliğe sahip olan thread'leri işleyip bitirmeye çalışacaktır; ardından high ve en sonda gariban thread'e sıra gelecektir. Ancak tam gariban thread'e sıra gelecekken yine bir realtime thread gelirse ne olacaktır. Bu durumda bizim gariban thread açlıktan geberecekmidir Hayır elbette öyle olmayacaktır, bu gibi bir durumun oluşmaya başladığını anlayan işletim sistemi ilgili thread'in önceliğini bir müddetliğine yükseltecek ve onun da gönlünü alacak sonra önceliğini tekrar eski durumuna geri çekecektir. Bu işleme priority boosting demişler.
Kısacası threading esasen kolay bir konudur, yeterki kısıtlı kaynaklarınızın olduğunu bilin ve kaynakları adil bir şekilde yönetmenize yardımcı olması için hizmetinize sunulan senkronizasyon nesnenerini düzgün bir şekilde kullanın. O zaman çok ciddi sorunlar ile karşılaşma ihtimaliniz epey bir azalır.
Neyse konumuz açlık değil elbette, ama aklıma gelince bir iki kelam edeyim dedim. Yukarıda gönderdiğim örneklerdeki deadlockları çözmek için ilkinde; TThread.Synchronize yerine TThread.Queue yazabilirsiniz. Bu metod; uygulamanızın ana thread'inin bloklu olup olmadığı ile ilgilenmez; yapacağı işler kuyruğunun en altına bir işi atıp geri döner. Ana thread'iniz yaptığı işi bitirdiğinde bir sonraki işi kuyruktan alıp işleyebilir ve deadlock'a müsaade edilmemiş olur.
İkinci örnekte; SendMessage yerine PostMessage kullanabilirsiniz. Dediğim gibi SendMessage blocking bir API'dir ve karşıda mesajı alacak olan thread'in mesajı işleyip geriye dönmesini bekler. Oysaki PostMessage tıpkı TThread.Queue gibi davranır ve ilgili mesajın hedef thread'in mesaj kuyruğunun en sonuna ekler. İlla SendMessage çağrımı yapmam gerekiyor diyorsanız; SendMessage yerine SendMessageTimeOut'u kullanmanızı öneririm.
Ayrıca en son olarak belirttiğim GetWindowText API'si gibi başka API'lerde vardır ve kullandığınız API'lerin msdn açıklamalarını okumak için zaman ayırmanızın önemli olduğunu söyleyebilirim. GetWindowText API'si de yukarıdaki örnekte deadlock'a yol açacaktır çünkü iç yapısında hedef pencerenin başlık bilgisini elde edebilmek için hedef pencereye SendMessage API'si ile WM_GETTEXT mesajını iletir ve yanıtını bekler.
Bu ve buna benzer Deadlock senaryolarını çoğaltabilirsiniz. Bu nedenle, birden fazla thread ile işlem yapacak ve ortak kaynaklara müracaat edecekseniz; gidin bir bardak kahve alın ve önce bir kağıt üzerinde hangi thread hangi kaynağa ne zaman ve nasıl ulaşacak diye yazın/çizin. Ardından kodlamaya geçin.
Şimdi; bu bilgilerin ışığında artık bir yada birden fazla thread'in birbirlerini beklemelerinden kaynaklanan Deadlock senaryolarını oluşturabileceğinize göre; 3ncü soru hakkında ne düşünüyorsunuz ?
Deadlock durumda olan, yada sonsuz bekleme durumunda olan thread'lerimizi nasıl tespit edeceğiz ?
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim:
Re: Challenge 6
benim anlamadigim kisim surasi.
WaitForSingleObject , thread bitene kadar ana threadi bekletiyor. bu bekleme esnasinda ana threade herhangi bir mesaj bile iletilmiyor.
madem ana thread ikinci threadi bekleyecek neden thread kullaniyoruz ? ikinci threadde ki islemi ana thread icinde yapsak yine ayni kapiya cikmiyor muyuz ?
WaitForSingleObject , thread bitene kadar ana threadi bekletiyor. bu bekleme esnasinda ana threade herhangi bir mesaj bile iletilmiyor.
madem ana thread ikinci threadi bekleyecek neden thread kullaniyoruz ? ikinci threadde ki islemi ana thread icinde yapsak yine ayni kapiya cikmiyor muyuz ?
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim:
Re: Challenge 6
debugger ekranindan bakip anlarim
Wait Chain Traversal ile bulunuyormus ama detayini tam olarak bilmiyorum
Wait Chain Traversal ile bulunuyormus ama detayini tam olarak bilmiyorum