(12-12-2021, Saat: 14:47)mrmarman Adlı Kullanıcıdan Alıntı: Merhaba.
* Forumlardaki başlıklara bakarken aklıma geldi. Bir proje tasarlayarak merakımı gidermeye karar verdim. Thread içerikli ve eksiklerimi pekiştirmek amaçlı.
* En altta düşündüğüm ve çalışacağına inancımın tam olduğu bir çözüm de var ama konuyu özetlemiş olayım isterim :
* Örnek sorunsal çekirdeği vereyim :
* 13 tane dosya indireceğiz. ( Özellikle 13 dedim bir tane 10'lu bir tane 3'lü thread beklemesi ile küsuratlı olsun istedim... )
* Ağ sağlığı için en fazla 10 thread aynı anda çalışsın istiyoruz. ( Bu bile fazla ama örnekleme kolay olsun diye böyle diyelim. Mantığı kurunca ekonomisi yapılır...)
* Yalnız bir sonraki sekans için 10 thread'in 10'unu da bitene kadar beklemeyelim, 10'dan bitenin yerine kalan 3'den bir tanesi hemen devreye girsin. Çünkü 10 thread içerisinde en yavaş olan thread hızı tüm bekleme süresini belirleyecektir bunu biliyoruz.
* Genel uygulamam şu şekildedir.
Aklıma gelen soru bu noktada...
- Bir ana proje MainThread çalışıyor.
- Bu ana projeye işleri üstelenecek bir Worker thread eklerim. Böylece ana proje dahili işlemlerde bloke olmuyor. Eventleri Syncronize vb. ile çalıştırıp haberleştiriyoruz vs..
- Ardışık olarak internetten bir sürü dosya indirmek istiyoruz.
- Bunun için WaitForMultipleObject'i başarılı bir şekilde kullanıyoruz. Mesela sadece 10 tane dosya simültane indirsin, tümü bitince sonraki 10 tane dosya indirme işlemine başlasın şekilde yürüyoruz.
İşte sorum bu noktada...
- Thread sayısını sınırlandırdığımda (10 tane Threadhandle'ini bir Array ile vererek) WaitForMultipleObject ile (TRUE ile hepsi bitince talimatıyla) tüm dosyalar indiğinde WAIT_OBJECT_0 şeklinde bir sonuç ile işlem başarılı bir şekilde sonuçlanarak bir sonraki sekansa geçmek için sebebim oluyor.
- Eğer hepsi bitince talimatını FALSE yaparsam önce hangisi biterse onun index nosu ile ( WAIT_OBJECT_0+1, WAIT_OBJECT_0+5, vb. ) array içerisinden hangisinin işi önce bitmişse onun index nosunu alıyorum.
10 Thread'in 10'unu da beklemeden bitenin yerine yenisini başlatmak istersem hemen altında yeni bir WaitFor kurmak için nasıl bir strateji kurmak gerekli.
- Düşüncemde yer eden çözüm; Recursive bir yapı ile "waitformultipleobject" / waitfor all = "FALSE" olarak ilkinde 10 diğerlerinde tek elemanlı alt alta dallanan bir single çalışan multiobject yapısı gibi bir beklenti.
- Recursive derken kendi içinde kendini çağıran ama ilk çağrıda maksimum thread sayısı iken içe dallandığında daima 1 elemanlı array ile bekleyen bir yapı.
* Bu noktada çözmem gereken sorunsal ise alta dallandıktan sonra yine bir WaitFor koyup devam etmekte olan, ARRAY içindeki tüm thread'lerin bittiğinden de emin olmak için nasıl bir yapı kuracağım...?! Sanki Array içinde kalan elemanları da SUB WaitFor için gönderip onların da waitfor'a dahil olmasını beklemek gibi bir garip düşünce de oluşmadı değil...
* Bu şekilde çözebileceğimi biliyorum ve inanıyorum ama kolları sıvamadan sorayım dedim.... Mantıklı mıdır yoksa alternarifi var mıdır ?
* Başlığa yabancılık çekenler için anahtar kelimeleri vereyim :
* WaitForSingleObject 1 tread sonlanana kadar procedure bekletir ve bitince procedure kaldığı yerden devam eder.
* WaitForMultipleObjects ( n ) adet thread bekler... bWaitAll= TRUE ise tümü bitmediği sürece bekler procedure de bekler, bWaitAll = FALSE ise en az birisi biterse, bekleme işlemi sona erer ama diğer threadler çalışmaya devam ederken procedure yeniden yürümeye başlar.
Hocam yoğun thread kullanımında, bu threadler her zaman oluşturulabilir anlamı taşımaz, unable to create thread cevabı sistemden alabilirsiniz, thread create exception a düşer, uygulama kitlenmiş bir şekilde beklemeye geçer, bunun ne zaman olacağınıda bilemeyiz ancak olması olasıdır,
bu sebeple sırf socket read write blocking yapılıyorsa, win ortamında async soket kullanmayı tavsiye ederim,
böylelikle event notify mantığıyla ve uygulama blocklanmadan çok daha az bellek kullanan performanslı bir uygulamaya ortaya çıkar,
örneğin 5k client bağlantısı için 5k thread yaratmak hem client hem server soket için pek mantıklı değildir çünkü.
https://github.com/fundamentalslib/funda...ce/Sockets

