Konuyu Paylaş : facebook gplus twitter

Konuyu Oyla:
  • Derecelendirme: 5/5 - 1 oy
  • 1
  • 2
  • 3
  • 4
  • 5
100 puan değerinde (Threading)
#1
Uygulamanızın ana thread'ini durdurmadan(kullanıcı ile etkileşimli kalmaya devam edecek şekilde); bir başka senkronizayson nesnesini ya da bir thread'i nasıl beklersiniz ?

Örneğin;

procedure TForm1.Button1Click(Sender : TObject);
var
  Thrd : TThread;
begin
  Thrd := TThread.CreateAnonymousThread(
    procedure
    begin
      Sleep(10000);
    end
  );


  Thrd.Start;

  // Yukarıdaki thread kendi içinde 10 sn bekliyor. Biz de tam bu nokta da yukarıdaki thread'in bitmesini bekleyeceğiz. Ama nasıl ;-)

  AnaThreadDonmadanBuradaYukaridakiThreadiBekleyelim;

  Memo1.Lines.Add('Thread bitti');
end;

Önemli bir husus olduğu için 100 puan vereceğim beklediğim cevaba. Ancak, kayda değer cevaplara da yine puan vereceğim. Tabii teori değil, kod istiyoruz ;-)
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#2
Merhaba.

Aklıma direkt anonim thread nasıl syncronize edilir sorusu geliyor. 
Dolayısıyla bir thread'e göre global ama procedure içerisine yerleşik bir boolean değişken koyup bunun true veya false durumuna göre bir While NOT degisken şeklinde bir döngüde Application.ProcessMessages döngüsü gibi geliyor. Sonra da geriye kalan bu değişkeni thread ile senkron etmek.

Şöyle bir şey denedim.
procedure TForm1.Button1Click(Sender : TObject);
Var
 xDurum : boolean;
 Thrd   : TThread;
begin
 Thrd := TThread.CreateAnonymousThread(
   procedure
   begin
     Sleep(10000);
     TThread.Synchronize ( TThread.CurrentThread,
                             procedure ()
                             begin
                               xDurum := True;
                             end
                         );
   end
 );

 Thrd.Start;
 while NOT xDurum do
 begin
   Application.ProcessMessages;
 end;

 // Yukarıdaki thread kendi içinde 10 sn bekliyor. Biz de tam bu nokta da yukarıdaki thread'in bitmesini bekleyeceğiz. Ama nasıl ;-)
//AnaThreadDonmadanBuradaYukaridakiThreadiBekleyelim;
 Memo1.Lines.Add('Thread bitti');
end;

- Her zaman olduğu gibi soru süper üstadım tebrikler. 

 - Değişken atama için syncronize lazım mı değil mi ? Onu hiç düşünmedim  Smile  Bir method'a değer aktarmıyoruz sonuçta. Direkt bu değişkene de eşitleyince de olur bence. 

Arrow Başlığı okuyanlara anlatıyorum, tercihen sleep kullanmak durumunda olsaydım 10000 milisaniye değil de 10 milisaniye dilimler halinde 1'den 1000'e kadar bir döngü kurar içinde application.processmessages koyardım. Böylece 10 milisaniyelik donmalar beni üzmezdi.

Arrow Kendi uyguladığım method ise GetTickCount + 10 saniye ( 10000 milisaniye ) değerini bir değişkene alır, while döngüsünde güncel GetTickCount'un bu değişkendeki değerin üzerine çıktığı anı yine application.processmessages ile beklemek şeklinde oluyor.
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif


Cevapla
#3
(30-04-2018, Saat: 09:25)mrmarman Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlMerhaba.

Aklıma direkt anonim thread nasıl syncronize edilir sorusu geliyor. 
Dolayısıyla bir thread'e göre global ama procedure içerisine yerleşik bir boolean değişken koyup bunun true veya false durumuna göre bir While NOT degisken şeklinde bir döngüde Application.ProcessMessages döngüsü gibi geliyor. Sonra da geriye kalan bu değişkeni thread ile senkron etmek.

Şöyle bir şey denedim.
procedure TForm1.Button1Click(Sender : TObject);
Var
 xDurum : boolean;
 Thrd   : TThread;
begin
 Thrd := TThread.CreateAnonymousThread(
   procedure
   begin
     Sleep(10000);
     TThread.Synchronize ( TThread.CurrentThread,
                             procedure ()
                             begin
                               xDurum := True;
                             end
                         );
   end
 );

 Thrd.Start;
 while NOT xDurum do
 begin
   Application.ProcessMessages;
 end;

 // Yukarıdaki thread kendi içinde 10 sn bekliyor. Biz de tam bu nokta da yukarıdaki thread'in bitmesini bekleyeceğiz. Ama nasıl ;-)
//AnaThreadDonmadanBuradaYukaridakiThreadiBekleyelim;
 Memo1.Lines.Add('Thread bitti');
end;

- Her zaman olduğu gibi soru süper üstadım tebrikler. 

 - Değişken atama için syncronize lazım mı değil mi ? Onu hiç düşünmedim  Smile  Bir method'a değer aktarmıyoruz sonuçta. Direkt bu değişkene de eşitleyince de olur bence. 

Arrow Başlığı okuyanlara anlatıyorum, tercihen sleep kullanmak durumunda olsaydım 10000 milisaniye değil de 10 milisaniye dilimler halinde 1'den 1000'e kadar bir döngü kurar içinde application.processmessages koyardım. Böylece 10 milisaniyelik donmalar beni üzmezdi.

Arrow Kendi uyguladığım method ise GetTickCount + 10 saniye ( 10000 milisaniye ) değerini bir değişkene alır, while döngüsünde güncel GetTickCount'un bu değişkendeki değerin üzerine çıktığı anı yine application.processmessages ile beklemek şeklinde oluyor.

Ellerinize sağlık üstadım. İlginize teşekkür ederim. Sizin kullanımınızda bir sıkıntı olmaz. Çünkü değişken lokal ve o değişkene erişen başka bir thread yok. Application.ProcessMessages önerisi geleceğini biliyordum.

Şimdi sizden ricam, uygulamanızın kullandığı CPU yüzdesine bakın ;-)

Asıl amacımız CPU'yu yormayacak bir çözüm. İhtiyaç hasıl olur ise, ipucu verebilirim; böylece o istikamette yürüyebiliriz.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#4
Anladım.  Teşekkürler.

Oltaya düştük demek Smile
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif


Cevapla
#5
(30-04-2018, Saat: 09:44)mrmarman Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlAnladım.  Teşekkürler.

Oltaya düştük demek Smile

Estağfirullah üstadım. Sizinki çok doğal bir yanıt ve makul bir yanıt aynı zamanda. Ancak, çok çok daha iyi ve efektif olanı mevcut.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#6
Smile 
Selam @Tuğrul HELVACI Hocam
Ben @mrmarman  hocamın koduna sadece  TThread.Sleep(10); fonsiyonunu ekledim. ondan örnek alıp. (Tırtıklayıp )
CPU nerdeyse %1 bile yer işgal etmiyor. 
Çok fazla Thread kullanan biri olarak doğru cevabı sabırsızlıkla bekliyorum.

while NOT xDurum do
 begin
  TThread.Sleep(10);
  Application.ProcessMessages;
end;
Bu dünyada kendine sakladığın bilgi ahirette işine yaramaz. 
Cevapla
#7
Sleep(10) satırını ilgili döngünün içinde kullanmak; işletim sistemine uygulamanızın main thread'ini 10 milisaniye boyunca durdur demektir. Ancak realite'de bu süre 10 milisaniyeden çok daha uzun olacaktır. Çünkü thread'iniz işletim sisteminin scheduler'ı tarafından durdurulmuş ve çalıştırılma sırası diğer thread'lere geçmiştir. Round Robin, priority round robin yapısında thread'inize boosting bile uygulansa; threadinize geri dönüş süresi 10 milisaniyeden uzun olacaktır.

Dolayısı ile istediğimiz şey Sleep değil. Bu arada yeri gelmişken Sleep(0)'dan bahsetmeden olmaz. Sleep(0) özel bir anlam ifade eder. Sleep(0) işletim sistemine; "eğer çalıştırılmak için bekleyen başka thread'ler var ise buyur onları çalıştır kardeşim, benim daha fazla çalışma zamanına ihtiyacım yok. Ama bekleyen thread yoksa, ben çalışmaya devam ederim" demektir.

Sleep(0) = Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol.

Benim sizlerden araştırmanızı istediğim API'ler aşağıdakiler olacaktır. Tabii öğrenmek isteyene;
Cevaplarınızı bekliyorum Smile
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#8
procedure TForm1.Button1Click(Sender : TObject);
Var
Thrd   : TThread;
begin
Thrd := TThread.CreateAnonymousThread(
  procedure
  begin
    Sleep(10000);
    TThread.Synchronize ( TThread.CurrentThread,
                            procedure ()
                            begin
                             memo1.lines.add('İşlem bitti');
                            end
                        );
  end
);

Thrd.Start;
Böyle çok güzel çalışıyor hocam, bence bozmayalım Smile
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
WWW
Cevapla
#9
(30-04-2018, Saat: 11:51)esistem Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
procedure TForm1.Button1Click(Sender : TObject);
Var
Thrd   : TThread;
begin
Thrd := TThread.CreateAnonymousThread(
  procedure
  begin
    Sleep(10000);
    TThread.Synchronize ( TThread.CurrentThread,
                            procedure ()
                            begin
                             memo1.lines.add('İşlem bitti');
                            end
                        );
  end
);

Thrd.Start;
Böyle çok güzel çalışıyor hocam, bence bozmayalım Smile

Herhangi bir senkronizasyon nesnesini beklemeye ihtiyacınız olduğunda ve ana thread'iniz kilitlendiğinde ya da çok fazla CPU kullandığında; ilgili konumuza yeniden bekleriz o halde sizi sevgili üstadım Wink
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#10
Benim cevap hakkım yok dimi Smile
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
Kuvvete dayanamayan adalet aciz, 
Adalete dayanamayan kuvvet zalimdir.
WWW
Cevapla

Konuyu Paylaş : facebook gplus twitter





Konuyu Okuyanlar: 1 Ziyaretçi