14-12-2021, Saat: 21:37
@Tuğrul HELVACI
Biraz önce örnek kodu inceledim. Zekice kurgulanmış tebrik ederim.
Mantık ; CPU çekirdek sayısı x 2 adet thread dizisini peşinen oluşturup çalışır halde bırakarak, sırasıyla işleri bunlara atamak. Thread görevi bitirdiğinde de çalışır kalmasına izin vermek.
Böylece thread oluştur thread bitince yenisini oluştur vs. derdi artık yok hükmünde.
* Başlığı okuyanlar için aşağıdaki listede görülmesi gereken 1744 Id'li thread (3) kere görev almış, 12344 Id'li thread (2) defa görev almış.
@vkamadan paylaştığınız örneğiniz de sorduğum thread limitleme konusuna tam cevap niteliğinde. Ancak bir kısıt var. Şöyle ki aşağıdaki şekilde kurduğumda tüm threadler peşinen create ediliyor. Yani aşağıdaki akışa bakılınca, bu döngü 10.000 olsaydı 10.000 tane create edip sonra bunları TSemaphore.Create ile belirlediğimiz sayı kadarlık gruplar halinde çalıştıracaktı anlamına geliyor.
* Sonradan Embarcadero help ile incelediğimde "TSemaphore" kullanımının aslında benim istediğim şekilde thread sayısı sınırlamaktan öte / farklı olarak aslında threadler ile ortak / paylaşılan kaynaklara limitli sayılarda thread ile kontrollü ve güvenli olarak erişim yönetimi için kullanıldığını görüyorum.
@vedat35 vallahi söylediğiniz yeni anladım desem. "5k client / 5k server derken" zaten sorumun amacı yüzlerce veya binlerce kaynak için thread sayısı dinamiğini sınırlamak. Yani örneğin yukarıdaki örnekte maksimum "cpucore * 2" sağlıklı limitten sadece 3'erli gruplar haline iş için thread açılsın sonra kapananın yerine yenisi veya yenileri açılsın ama 3'ü geçmesin gibisinden bir beklentim vardı.
@Tuğrul HELVACI ise işi kökünden halledip thread limit kadar oluşturup işleri bunlara dağıtarak çözüm önerisinde bulunmuş.
Hani "Matrix" filminin vurucu diyaloglarından biri ki izleyenleriniz vardır.
- Soru "kaşığı zihin gücüyle nasıl büktüğümü merak ediyorsun değil mi?... Cevap "Aslında kaşık yok."
Genel olarak bu minvalde zihnim aydınlandı.
* Sadece nesnel programcılık için faydalı olsa da generics tipler konusuna biraz soğuğum. Bunu TThreadList / TList vb. ile yapmaya çalışacağım.
* TObjectList yerine TThreadList kullanınca MemoryLeak sorunu yaşadım onun üzerine çalışayım.
Tekrar önerileriniz ve vakit ayırma inceliğiniz için teşekkürler.
Biraz önce örnek kodu inceledim. Zekice kurgulanmış tebrik ederim.
Mantık ; CPU çekirdek sayısı x 2 adet thread dizisini peşinen oluşturup çalışır halde bırakarak, sırasıyla işleri bunlara atamak. Thread görevi bitirdiğinde de çalışır kalmasına izin vermek.
Böylece thread oluştur thread bitince yenisini oluştur vs. derdi artık yok hükmünde.
* Başlığı okuyanlar için aşağıdaki listede görülmesi gereken 1744 Id'li thread (3) kere görev almış, 12344 Id'li thread (2) defa görev almış.
Kod: (Select All)
2688 ThreadID başlatıldı
8408 ThreadID başlatıldı
11648 ThreadID başlatıldı
16760 ThreadID başlatıldı
9320 ThreadID başlatıldı
6136 ThreadID başlatıldı
1744 ThreadID başlatıldı
16940 ThreadID başlatıldı
16620 ThreadID başlatıldı
9360 ThreadID başlatıldı
11000 ThreadID başlatıldı
4892 ThreadID başlatıldı
8948 ThreadID başlatıldı
5512 ThreadID başlatıldı
12344 ThreadID başlatıldı
13684 ThreadID başlatıldı
***********************************
Random Value: 990857453, Worker Thread ID: 1744, Çalışma zamanı: 1799, Tek Sayı: 245449623536840529, Çift Sayı: 245449623041411802
Random Value: 1449733987, Worker Thread ID: 12344, Çalışma zamanı: 2601, Tek Sayı: 525432158990596036, Çift Sayı: 525432158265729042
Random Value: 1490167247, Worker Thread ID: 5512, Çalışma zamanı: 2820, Tek Sayı: 555149606752973376, Çift Sayı: 555149606007889752
Random Value: 736899495, Worker Thread ID: 1744, Çalışma zamanı: 1412, Tek Sayı: 135755216801263504, Çift Sayı: 135755216432813756
Random Value: 1352173282, Worker Thread ID: 1744, Çalışma zamanı: 2555, Tek Sayı: 457093146138662881, Çift Sayı: 457093146814749522
Random Value: 1800462294, Worker Thread ID: 12344, Çalışma zamanı: 3314, Tek Sayı: 810416118028935609, Çift Sayı: 810416118929166756
2688 ThreadID durduruldu
8408 ThreadID durduruldu
11648 ThreadID durduruldu
16760 ThreadID durduruldu
9320 ThreadID durduruldu
6136 ThreadID durduruldu
1744 ThreadID durduruldu
16940 ThreadID durduruldu
16620 ThreadID durduruldu
9360 ThreadID durduruldu
11000 ThreadID durduruldu
4892 ThreadID durduruldu
8948 ThreadID durduruldu
5512 ThreadID durduruldu
12344 ThreadID durduruldu
13684 ThreadID durduruldu@vkamadan paylaştığınız örneğiniz de sorduğum thread limitleme konusuna tam cevap niteliğinde. Ancak bir kısıt var. Şöyle ki aşağıdaki şekilde kurduğumda tüm threadler peşinen create ediliyor. Yani aşağıdaki akışa bakılınca, bu döngü 10.000 olsaydı 10.000 tane create edip sonra bunları TSemaphore.Create ile belirlediğimiz sayı kadarlık gruplar halinde çalıştıracaktı anlamına geliyor.
* Sonradan Embarcadero help ile incelediğimde "TSemaphore" kullanımının aslında benim istediğim şekilde thread sayısı sınırlamaktan öte / farklı olarak aslında threadler ile ortak / paylaşılan kaynaklara limitli sayılarda thread ile kontrollü ve güvenli olarak erişim yönetimi için kullanıldığını görüyorum.
var
ASemaphore : TSemaphore;
procedure TForm1.BitBtn4Click(Sender: TObject);
var
i : Integer;
begin
if NOT Assigned(ASemaphore)
then ASemaphore := TSemaphore.Create(nil, 3, System.CPUCount*2, '');
for i := 1 to 13 do
begin
TThread.CreateAnonymousThread(
procedure
var
ThId : word;
begin
ThId := i;
TThread.Queue( nil, procedure begin form1.Memo1.Lines.Add(format('Thread %.2d created and running (%s) ', [ThId, DateTimeToStr(now)])); end );
WaitForSingleObject(ASemaphore.Handle, INFINITE);
Sleep(3000);
ASemaphore.Release(1);
TThread.Queue( nil, procedure begin form1.Memo1.Lines.Add(format('Thread %.2d exit (%s)', [ThId, DateTimeToStr(now)])); end );
end
).start;
Application.ProcessMessages;
sleep(60);
end;
end;
Kod: (Select All)
Thread 01 created and running (14.12.2021 21:09:17)
Thread 02 created and running (14.12.2021 21:09:17)
Thread 03 created and running (14.12.2021 21:09:17)
Thread 04 created and running (14.12.2021 21:09:17)
Thread 05 created and running (14.12.2021 21:09:17)
Thread 06 created and running (14.12.2021 21:09:17)
Thread 07 created and running (14.12.2021 21:09:17)
Thread 08 created and running (14.12.2021 21:09:17)
Thread 09 created and running (14.12.2021 21:09:17)
Thread 10 created and running (14.12.2021 21:09:17)
Thread 11 created and running (14.12.2021 21:09:17)
Thread 12 created and running (14.12.2021 21:09:18)
Thread 13 created and running (14.12.2021 21:09:18)
Thread 01 exit (14.12.2021 21:09:20)
Thread 02 exit (14.12.2021 21:09:20)
Thread 03 exit (14.12.2021 21:09:20)
Thread 09 exit (14.12.2021 21:09:23)
Thread 13 exit (14.12.2021 21:09:23)
Thread 08 exit (14.12.2021 21:09:23)
Thread 07 exit (14.12.2021 21:09:26)
Thread 10 exit (14.12.2021 21:09:26)
Thread 11 exit (14.12.2021 21:09:26)
Thread 12 exit (14.12.2021 21:09:29)
Thread 05 exit (14.12.2021 21:09:29)
Thread 04 exit (14.12.2021 21:09:29)
Thread 06 exit (14.12.2021 21:09:32)@vedat35 vallahi söylediğiniz yeni anladım desem. "5k client / 5k server derken" zaten sorumun amacı yüzlerce veya binlerce kaynak için thread sayısı dinamiğini sınırlamak. Yani örneğin yukarıdaki örnekte maksimum "cpucore * 2" sağlıklı limitten sadece 3'erli gruplar haline iş için thread açılsın sonra kapananın yerine yenisi veya yenileri açılsın ama 3'ü geçmesin gibisinden bir beklentim vardı.
@Tuğrul HELVACI ise işi kökünden halledip thread limit kadar oluşturup işleri bunlara dağıtarak çözüm önerisinde bulunmuş.
Hani "Matrix" filminin vurucu diyaloglarından biri ki izleyenleriniz vardır.
- Soru "kaşığı zihin gücüyle nasıl büktüğümü merak ediyorsun değil mi?... Cevap "Aslında kaşık yok."
Genel olarak bu minvalde zihnim aydınlandı.
* Sadece nesnel programcılık için faydalı olsa da generics tipler konusuna biraz soğuğum. Bunu TThreadList / TList vb. ile yapmaya çalışacağım.
* TObjectList yerine TThreadList kullanınca MemoryLeak sorunu yaşadım onun üzerine çalışayım.
Tekrar önerileriniz ve vakit ayırma inceliğiniz için teşekkürler.
Saygılarımla
Muharrem ARMAN

Muharrem ARMAN


