C # 'da iş parçacığı havuzu ne zaman kullanılır? [kapalı]


127

C # ile çok iş parçacıklı programlamayı öğrenmeye çalışıyorum ve iş parçacığı havuzunu kullanmak yerine kendi iş parçacığımı oluşturmanın en iyi olduğu zaman konusunda kafam karıştı. Bir kitap, yalnızca küçük görevler için bir iş parçacığı havuzu kullanılmasını önerir (bu ne anlama gelirse gelsin), ancak gerçek bir kılavuz bulamıyorum. Bu programlama kararını verirken göz önünde bulundurduğunuz bazı noktalar nelerdir?

Yanıtlar:


47

Sürekli işlem gerektiren çok sayıda mantıksal göreviniz varsa ve bunun paralel olarak yapılmasını istiyorsanız, pool + zamanlayıcıyı kullanın.

Uzak sunuculardan veya disk erişiminden bir şeyler indirmek gibi IO ile ilgili görevleri aynı anda yapmanız gerekiyorsa, ancak bunu birkaç dakikada bir yapmanız gerekiyorsa, ardından kendi iş parçacıklarınızı oluşturun ve işiniz bittiğinde onları kapatın.

Düzenleme: Bazı hususlar hakkında, veritabanı erişimi, fizik / simülasyon, AI (oyunlar) ve birçok kullanıcı tanımlı görevi işleyen sanal makinelerde çalıştırılan komut dosyası içeren görevler için iş parçacığı havuzlarını kullanıyorum.

Normalde bir havuz işlemci başına 2 iş parçacığından oluşur (bugünlerde büyük olasılıkla 4), ancak kaç tanesine ihtiyacınız olduğunu biliyorsanız, istediğiniz iş parçacığı miktarını ayarlayabilirsiniz.

Düzenleme: Kendi iş parçacıklarınızı oluşturmanın nedeni bağlam değişiklikleridir (bu, iş parçacıklarının belleğiyle birlikte sürece girip çıkması gerektiğinde). Yararsız bağlam değişikliklerine sahip olmak, mesela konularınızı kullanmadığınızda, söylenebileceği gibi onları ortalıkta bırakmak, programınızın performansının kolayca yarı yarıya düşmesine neden olabilir (diyelim ki 3 uyuyan konu ve 2 aktif konu var). Böylece, iş parçacığı indirenler sadece bekliyorlarsa, tonlarca CPU tüketiyorlar ve gerçek uygulamanız için önbelleği soğutuyorlar


2
Tamam, ama neden böyle yaklaştığınızı açıklayabilir misiniz? Örneğin, uzak sunuculardan indirmek için iş parçacığı havuzunu kullanmanın veya disk GÇ'yi kullanmanın dezavantajı nedir?

8
Bir eşzamanlama nesnesi (olay, semafor, muteks, vb.) Üzerinde bir evre bekliyorsa, iş parçacığı CPU tüketmez.
Brannon

7
Brannon'un dediği gibi, ortak bir efsane, birden fazla iş parçacığı yaratmanın performansı etkilediğidir. Aslında, kullanılmayan iş parçacıkları çok az kaynak tüketir. Bağlam anahtarları, yalnızca çok talep gören sunucularda sorun olmaya başlar (bu durumda, bir alternatif için G / Ç tamamlama bağlantı noktalarına bakın).
FDCastel

12
Boştaki iş parçacıkları performansı etkiler mi? Nasıl beklediklerine bağlı. İyi yazılmışsa ve bir senkronizasyon nesnesini bekliyorsa, hiçbir CPU kaynağı tüketmemelidirler. Sonuçları kontrol etmek için periyodik olarak uyanan bir döngüde beklerseniz, CPU israfına neden olur. Her zaman olduğu gibi, iyi kodlamaya bağlı.
Bill

2
Boşta yönetilen iş parçacıkları, yığınları için bellek tüketir. Varsayılan olarak, iş parçacığı başına 1 MiB'dir. Bu yüzden tüm iş parçacıklarının çalışması daha iyidir.
Vadym Stetsiak

48

Diğer dillerle aynı nedenlerle C # 'da bir iş parçacığı havuzu kullanmanızı öneririm.

Çalışan iş parçacığı sayısını sınırlamak istediğinizde veya bunları oluşturma ve yok etme ek yükünü istemediğinizde, bir iş parçacığı havuzu kullanın.

Küçük görevlerle, okuduğunuz kitap, kısa ömürlü görevler anlamına gelir. Yalnızca bir saniye çalışan bir iş parçacığı oluşturmak on saniye sürerse, bu havuzları kullanmanız gereken yerlerden biridir (gerçek rakamlarımı göz ardı edin, önemli olan orandır).

Aksi takdirde, zamanınızın büyük bir kısmını, sadece yapmak istedikleri işi yapmak yerine, iş parçacıkları oluşturmak ve yok etmek için harcarsınız.


28

İşte .Net'teki iş parçacığı havuzunun güzel bir özeti: http://blogs.msdn.com/pedram/archive/2007/08/05/dedicated-thread-or-a-threadpool-thread.aspx

Gönderi ayrıca iş parçacığı havuzunu kullanmamanız ve bunun yerine kendi iş parçacığınızı başlatmanız gerektiğinde bazı noktalara da sahiptir.


8
Bağlantı için -1. Eminim iyi bir bağlantıdır, ancak SO'nun kendi kendine yeterli olmasını bekliyorum.
Jon Davis

26
@ stimpy77 - o halde bu yanlış bir beklenti. SO asla kendi kendine yeterli olamaz, çünkü ne tüm sorular üzerinde nihai otorite ne de her bir konudaki tüm derinlemesine bilgiler, o konuya dokunan her bir SO yanıtında çoğaltılabilir (ve olmalıdır). (ve giden bağlantıları olan tüm SO kullanıcılarından gelen tüm yanıtları bir kenara bırakın, bir giden bağlantıya sahip olan tek başına Jon Skeet'in her yanıtını olumsuz oylayacak kadar itibarınız olduğunu bile sanmıyorum :-))
Franci Penov

2
Belki aşırı derecede özlü davrandım, belki de açıklığa kavuşturmalıyım. Bağlantılara karşı değilim. Sadece bağlantı içeren cevaplara karşıyım. Bunun bir cevap olduğunu sanmıyorum. Şimdi, bağlantılı içeriğin nasıl geçerli olduğunu özetlemek için yanıtın kısa bir özeti yayınlanmış olsaydı, bu kabul edilebilir olurdu. Ayrıca, buraya aynı soruna bir cevap aramak için geldim ve bu cevap beni rahatsız etti çünkü belirli bir soruna atıfta bulunarak ne söyleyebileceğine dair herhangi bir fikre sahip olmak için tıklamam gereken başka bir bağlantıydı. Her neyse, Jon Skeet bununla nerede ilişkilidir? Ve neden umursayayım?
Jon Davis

8
"Bu gönderiye gönderildikten iki yıl sonra geldiniz ve burada kopyaladığım her şey şimdiye kadar geçersiz kalmış olabilir." Bir bağlantı da olabilir. Bir bağlantı gönderirken kısa ama eksiksiz bir özet yayınlayın, bir bağlantının eskimiş mi yoksa ölü mü olduğunu asla bilemezsiniz.
Jon Davis

2
Uyarıcıya katılmıyorum: Yapılamazlıktan dolayı tonlarca bilgi içeren gönderiler ya da bu konuda birini çağırma fikri değil. Yine de, bir bağlantının çalışamaz hale gelmesi, içeriğin kullanımdan kaldırılmasından / unutulmasından daha muhtemel olduğunu söyleyebilirim . Bu nedenle, fırsat elverdiğinde daha fazla içerik güzeldir. Hepimiz (çoğunlukla) gönüllüyüz, bu yüzden aldığınız şey için minnettar olun - teşekkürler Franci :)
zanlok

14

Bu ücretsiz e-kitabı okumanızı şiddetle tavsiye ederim: Joseph Albahari'den C # Threading

En azından "Başlarken" bölümünü okuyun. E-kitap harika bir giriş sağlar ve aynı zamanda çok sayıda gelişmiş iş parçacığı bilgileri içerir.

İş parçacığı havuzunun kullanılıp kullanılmayacağını bilmek sadece başlangıçtır. Daha sonra, ihtiyaçlarınıza en uygun iş parçacığı havuzuna girme yöntemini belirlemeniz gerekecektir:

  • Görev Paralel Kitaplığı (.NET Framework 4.0)
  • ThreadPool.QueueUserWorkItem
  • Eşzamansız Temsilciler
  • BackgroundWorker

Bu e-kitap tüm bunları açıklıyor ve ne zaman kullanacağınıza karşı kendi ileti dizinizi oluşturmanıza yardımcı oluyor.


8

İş parçacığı havuzu, iş parçacıklarınız arasında bağlam geçişini azaltmak için tasarlanmıştır. Birkaç bileşenin çalıştığı bir işlemi düşünün. Bu bileşenlerin her biri, çalışan iş parçacıkları oluşturabilir. Sürecinizde ne kadar çok iş parçacığı varsa, bağlam değiştirme için o kadar çok zaman harcanır.

Şimdi, bu bileşenlerin her biri öğeleri iş parçacığı havuzunda sıraya koyuyor olsaydı, çok daha az bağlam değiştirme ek yüküne sahip olurdunuz.

İş parçacığı havuzu, CPU'larınız (veya CPU çekirdekleriniz) genelinde yapılan işi en üst düzeye çıkarmak için tasarlanmıştır. Bu nedenle, iş parçacığı havuzu varsayılan olarak işlemci başına birden çok iş parçacığı döndürür.

İş parçacığı havuzunu kullanmak istemediğiniz bazı durumlar vardır. Eğer I / O'yu bekliyorsanız veya bir olay için bekliyorsanız, o zaman o iş parçacığı havuzu iş parçacığını bağlarsınız ve başka kimse tarafından kullanılamaz. Aynı fikir uzun süren görevler için de geçerlidir, ancak uzun süren bir görevi oluşturan şey özneldir.

Pax Diablo da iyi bir noktaya işaret ediyor. İplikleri döndürmek ücretsiz değildir. Zaman alır ve yığın alanları için ek bellek kullanırlar. İş parçacığı havuzu, bu maliyeti amorti etmek için iş parçacıkları yeniden kullanacaktır.

Not: Veri indirmek veya disk G / Ç gerçekleştirmek için bir iş parçacığı havuzu iş parçacığı kullanmayı istediniz. Bunun için bir iş parçacığı havuzu iş parçacığı kullanmamalısınız (yukarıda özetlediğim nedenlerden dolayı). Bunun yerine eşzamansız G / Ç (diğer adıyla BeginXX ve EndXX yöntemleri) kullanın. Bir FileStreambu BeginReadve olurdu EndRead. Bir HttpWebRequestbu BeginGetResponseve olurdu EndGetResponse. Kullanımları daha karmaşıktır, ancak çok iş parçacıklı G / Ç gerçekleştirmenin uygun yoludur.


1
ThreadPool akıllı bir otomatikleştirmedir. "Kuyruğu yarım saniyeden fazla sabit kalırsa, iş parçacığı havuzunun kapasitesine kadar yarım saniyede bir olmak üzere daha fazla iş parçacığı oluşturarak yanıt verir" ( albahari.com/threading/#_Optimizing_the_Thread_Pool ). Ayrıca BeginXXX-EndXXX ile neredeyse eşzamansız işlemler ThreadPool aracılığıyla kullanılır. Bu nedenle, verileri indirmek için ThreadPool kullanılması normaldir ve genellikle örtük olarak kullanılır.
Artru

6

İş parçacığı açlığına eğilimli olduğundan işlemlerinin önemli, değişken veya bilinmeyen kısımlarını engelleyebilecek işlemler için .NET iş parçacığı havuzuna dikkat edin. Aşamalı işlemler üzerinden çok sayıda mantıksal soyutlama sağlayan .NET paralel uzantılarını kullanmayı düşünün. Ayrıca ThreadPool'da bir gelişme olması gereken yeni bir zamanlayıcı içerirler. Buraya bakın


2
Bunu zor yoldan keşfettik! ASP.Net, Threadpool kullanır görünür ve bu yüzden onu istediğimiz kadar agresif kullanamadık.
noocyte

3

İş parçacığı havuzunu yalnızca küçük görevler için kullanmanın bir nedeni, sınırlı sayıda iş parçacığı havuzu iş parçacığı olmasıdır. Biri uzun süre kullanılırsa, o iş parçacığının başka bir kod tarafından kullanılmasını durdurur. Bu birçok kez meydana gelirse, iş parçacığı havuzu tükenebilir.

İş parçacığı havuzunu kullanmanın ince etkileri olabilir - bazı .NET zamanlayıcıları iş parçacığı havuzu iş parçacıklarını kullanır ve örneğin ateşlenmez.


2

Uygulamanızın tüm ömrü boyunca olduğu gibi uzun süre yaşayacak bir arka plan göreviniz varsa, kendi iş parçacığınızı oluşturmak makul bir şeydir. Bir iş parçacığında yapılması gereken kısa işleriniz varsa, iş parçacığı havuzunu kullanın.

Çok sayıda iş parçacığı oluşturduğunuz bir uygulamada, iş parçacığı oluşturmanın ek yükü önemli hale gelir. İş parçacığı havuzunun kullanılması iş parçacıkları bir kez oluşturur ve bunları yeniden kullanır, böylece iş parçacığı oluşturma ek yükünü önler.

Üzerinde çalıştığım bir uygulamada, kısa ömürlü iş parçacıkları için iş parçacığı oluşturmaktan iş parçacığı havuzunu kullanmaya geçmek, uygulamanın sonuç vermesine gerçekten yardımcı oldu.


Lütfen "iş parçacığı havuzu" mu yoksa "iş parçacığı havuzu" mu demek istediğinizi netleştirin. Bunlar çok farklı şeylerdir (en azından MS CLR'de).
bzlm

2

Eşzamanlı olarak çalıştırılan birimlerle en yüksek performans için, kendi iş parçacığı havuzunuzu yazın, burada başlangıçta bir İş Parçacığı nesneleri havuzunun oluşturulduğu ve engellemeye (önceden askıya alınmış), çalıştırılacak bir bağlamı bekleyerek (standart bir arabirime sahip bir nesne) senin kodun).

Görevler ve İş Parçacıkları ile .NET ThreadPool hakkındaki pek çok makale, performans için bir karar vermeniz için ihtiyacınız olanı gerçekten veremiyor. Ama onları karşılaştırdığınızda, İplikler kazanır ve özellikle bir İplikler havuzu. CPU'lar arasında en iyi şekilde dağıtılırlar ve daha hızlı başlarlar.

Tartışılması gereken, Windows'un ana yürütme biriminin (Windows 10 dahil) bir iş parçacığı olduğu ve işletim sistemi bağlam değiştirme yükünün genellikle ihmal edilebilir olduğu gerçeğidir. Basitçe söylemek gerekirse, bu makalelerin çoğunun ikna edici kanıtlarını bulamadım, makale, bağlam değiştirmeyi veya daha iyi CPU kullanımını kaydederek daha yüksek performans iddia etsin.

Şimdi biraz gerçekçilik için:

Çoğumuz uygulamamızın deterministik olmasına ihtiyaç duymayacağız ve çoğumuz, örneğin genellikle bir işletim sistemi geliştirmeyle birlikte gelen iş parçacıklarıyla sert bir arka plana sahip değiliz. Yukarıda yazdıklarım yeni başlayanlar için değil.

Bu yüzden tartışmak en önemli şey, programlamanın kolay olanıdır.

Kendi iş parçacığı havuzunuzu oluşturursanız, yürütme durumunu izleme, askıya alma ve devam ettirme simülasyonunun nasıl yapılacağı ve uygulamanın nasıl iptal edileceği ile ilgilenmeniz gerekeceğinden, uygulama genelinde dahil olmak üzere, biraz yazmanız gerekir. kapat. Havuzunuzu dinamik olarak büyütmek isteyip istemediğiniz ve havuzunuzun hangi kapasite sınırlamasına sahip olacağıyla da ilgilenmeniz gerekebilir. Bir saat içinde böyle bir çerçeve yazabilirim ama bunun sebebi bunu defalarca yapmış olmam.

Bir yürütme birimi yazmanın belki de en kolay yolu bir Görev kullanmaktır. Bir Görevin güzelliği, bir tane oluşturabilmeniz ve onu kodunuzda sıralı olarak başlatabilmenizdir (yine de dikkatli olunabilir). Görevi iptal etmek istediğinizde işlenecek bir iptal belirteci iletebilirsiniz. Ayrıca, olayları zincirlemek için söz yaklaşımını kullanır ve bunun belirli bir değer türü döndürmesini sağlayabilirsiniz. Dahası, async ve await ile daha fazla seçenek mevcuttur ve kodunuz daha taşınabilir olacaktır.

Temelde, Görevler ve İş Parçacıkları ile .NET ThreadPool karşılaştırmasının artılarını ve eksilerini anlamak önemlidir. Yüksek performansa ihtiyacım olursa, thread kullanacağım ve kendi havuzumu kullanmayı tercih ediyorum.

Karşılaştırmanın kolay bir yolu, 512 İş Parçacığı, 512 Görev ve 512 ThreadPool iş parçacığı başlatmaktır. Başlangıçta Threads ile bir gecikme bulacaksınız (bu nedenle, neden bir iş parçacığı havuzu yazıyorsunuz), ancak 512 İş Parçacığının tümü birkaç saniye içinde çalışacak, Görevler ve .NET ThreadPool iş parçacıklarının başlaması birkaç dakika sürecek.

Aşağıda, her 30 saniyenin çalışması için verilen böyle bir testin (16 GB RAM'li i5 dört çekirdekli) sonuçları verilmiştir. Yürütülen kod, bir SSD sürücüsünde basit dosya G / Ç gerçekleştirir.

Test sonuçları


1
Bilginize, Görevler ve .NET İş Parçacıklarının .NET içinde eşzamanlı simülasyon olduğunu ve işletim sisteminin işletim sisteminde değil .NET içinde yürütülmesiyle birlikte simüle edildiğini söylemeyi unuttum - ikincisi eşzamanlı yürütmeleri yönetmede çok daha verimli. Görevler'i birçok şey için kullanıyorum, ancak ağır yürütme performansı için bir İşletim Sistemi İş Parçacığı kullanıyorum. MS, Görevler ve .NET Konularının daha iyi olduğunu iddia ediyor, ancak genel olarak .NET uygulamaları arasındaki eşzamanlılığı dengelemek için kullanılıyorlar. Ancak bir sunucu uygulaması, işletim sisteminin eşzamanlılığı yönetmesine izin vererek en iyi performansı gösterir.

Özel Threadpool'unuzun uygulanmasını görmek isterim. Güzel yaz!
Francis

Test Sonuçlarınızı anlamıyorum. "Units Ran" ne anlama geliyor? 34 taksiyi 512 konu ile karşılaştırır mısınız? Lütfen bunu açıklar mısınız?
Elmue

Birim, bir Task, Thread veya .NET ThreadPool çalışan iş parçacığında eşzamanlı olarak yürütmek için bir yöntemdir, benim testim başlatma / çalıştırma performansını karşılaştırır. Her testin sıfırdan 512 İş Parçacığı, 512 Görev, 512 İş Parçacığı Havuzu çalışan iş parçacığı oluşturmak için 30 saniye veya yürütülmek için bir bağlam bekleyen 512 başlatılmış İş Parçacığı havuzunu sürdürmek için 30 saniye vardır. Tasks ve ThreadPool çalışan iş parçacıkları yavaş bir dönüşe sahiptir, bu nedenle 30 saniye hepsini döndürmek için yeterli zaman değildir. Bununla birlikte, ThreadPool min işçi iş parçacığı sayısı ilk olarak 512 olarak ayarlanırsa, hem Tasks hem de ThreadPool iş parçacığı, neredeyse sıfırdan itibaren 512 Threads kadar hızlı dönecektir.


1

İş parçacığı havuzları, işlenecek iş parçacıklarından daha fazla göreviniz olduğunda harikadır.

Tüm görevleri bir iş parçacığı havuzuna ekleyebilir ve belirli bir zamanda çalışabilecek maksimum iş parçacığı sayısını belirtebilirsiniz.

Check out Bu MSDN'deki sayfayı: http://msdn.microsoft.com/en-us/library/3dasc8as(VS.80).aspx


Tamam sanırım bu benim diğer sorumla bağlantılı. Herhangi bir zamanda kaç tane iş parçacığınızın olduğunu nasıl anlarsınız?

Söylemesi zor. Performans testi yapmanız gerekecek. Bir noktadan sonra daha fazla konu eklemek size daha fazla hız vermeyecektir. Makinede kaç işlemci olduğunu öğrenin, bu iyi bir başlangıç ​​noktası olacaktır. Sonra oradan yukarı çıkın, eğer işlem hızı gelişmezse, daha fazla iş parçacığı eklemeyin.
lajos

1

Mümkünse her zaman bir iş parçacığı havuzu kullanın, mümkün olan en yüksek soyutlama düzeyinde çalışın. İplik havuzları sizin için iplikler yaratmayı ve yok etmeyi gizler, bu genellikle iyi bir şeydir!


1

İş parçacığı oluşturmanın pahalı sürecinden kaçındığınız için çoğu zaman havuzu kullanabilirsiniz.

Ancak bazı senaryolarda bir iş parçacığı oluşturmak isteyebilirsiniz. Örneğin, iş parçacığı havuzunu kullanan tek kişi siz değilseniz ve oluşturduğunuz iş parçacığı uzun ömürlü ise (paylaşılan kaynakları tüketmekten kaçınmak için) veya örneğin iş parçacığının yığın boyutunu kontrol etmek istiyorsanız.


1

Arkaplan işçisini araştırmayı unutmayın.

Pek çok durumda buluyorum, bana ağır kaldırmadan istediğimi veriyor.

Şerefe.


Çalışmaya devam eden basit bir uygulama olduğunda ve yapacak bir işiniz daha olduğunda, bu kodu yapmak çok kolaydır. yine de bağlantı sağlamadınız: şartname ve eğitim
zanlok

0

Genellikle başka bir iş parçacığı üzerinde bir şey yapmam gerektiğinde ve ne zaman çalışıp bittiğini gerçekten umursamadığımda Threadpool'u kullanırım. Günlüğe kaydetme veya hatta bir dosyayı arka planda indirmek gibi bir şey (bunu eşzamansız stil yapmanın daha iyi yolları olsa da). Daha fazla kontrole ihtiyacım olduğunda kendi iş parçacığımı kullanıyorum. Ayrıca bulduğum şey, "komut nesnelerini" depolamak için bir Threadsafe kuyruğu kullanmak (kendinizinkini kesmek), 1'den fazla iş parçacığında üzerinde çalışmam gereken birden fazla komutum olduğunda güzel. Böylece, bir Xml dosyasını bölebilir ve her bir öğeyi bir sıraya koyabilir ve ardından bu öğeler üzerinde bazı işlemler yapmak için çalışan birden çok iş parçacığına sahip olabilirsiniz. Üni'de (VB.net!) C #'a dönüştürdüğüm bir kuyruk yolu yazdım. Belli bir neden olmadan aşağıya ekledim (bu kod bazı hatalar içerebilir).

using System.Collections.Generic;
using System.Threading;

namespace ThreadSafeQueue {
    public class ThreadSafeQueue<T> {
        private Queue<T> _queue;

        public ThreadSafeQueue() {
            _queue = new Queue<T>();
        }

        public void EnqueueSafe(T item) {
            lock ( this ) {
                _queue.Enqueue(item);
                if ( _queue.Count >= 1 )
                    Monitor.Pulse(this);
            }
        }

        public T DequeueSafe() {
            lock ( this ) {
                while ( _queue.Count <= 0 )
                    Monitor.Wait(this);

                return this.DeEnqueueUnblock();

            }
        }

        private T DeEnqueueUnblock() {
            return _queue.Dequeue();
        }
    }
}

Bu yaklaşımla ilgili bazı sorunlar: - DequeueSafe () 'e yapılan çağrılar, bir öğe EnqueuedSafe () olana kadar bekleyecektir. Bir zaman aşımı belirterek Monitor.Wait () aşırı yüklerinden birini kullanmayı düşünün. - Bunu kilitlemek, en iyi uygulamalara göre değil, salt okunur bir nesne alanı oluşturun. - Monitor.Pulse () hafif olsa da, kuyruk yalnızca 1 öğe içerdiğinde onu çağırmak daha verimli olacaktır. - DeEnqueueUnblock () tercihen kuyruğu kontrol etmelidir. Sayım> 0. (Monitor.PulseAll veya bekleme zaman aşımları kullanılıyorsa gereklidir)
Craig Nicholson

0

İş parçacığı havuzunun çalışmayı mümkün olduğunca az gecikmeyle çekirdekler arasında dağıtmasını istedim ve bu diğer uygulamalarla iyi oynamak zorunda değildi. .NET iş parçacığı havuzu performansının olabileceği kadar iyi olmadığını buldum. Çekirdek başına bir iş parçacığı istediğimi biliyordum, bu yüzden kendi iş parçacığı havuzu ikame sınıfımı yazdım. Kod, burada başka bir StackOverflow sorusuna yanıt olarak verilmiştir .

İlk soruya gelince, iş parçacığı havuzu, tekrar eden hesaplamaları paralel olarak yürütülebilecek parçalara ayırmak için kullanışlıdır (sonucu değiştirmeden paralel olarak yürütülebileceklerini varsayarsak). Manuel iş parçacığı yönetimi, UI ve IO gibi görevler için kullanışlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.