Görevlerde C # ile çoklu iş parçacığı oluşturma

bilgisayar Programlama "thread" terimi, bir işlemcinin kodunuzda belirtilen bir yolu izlediği yürütme iş parçacığının kısaltmasıdır. Bir seferde birden fazla iş parçacığını izleme kavramı, çoklu görev ve çoklu iş parçacığı konusunu tanıtır.

Bir uygulamanın içinde bir veya daha fazla işlem vardır. Bir işlemi bilgisayarınızda çalışan bir program olarak düşünün. Şimdi her işlem bir veya daha fazla iş parçacığına sahiptir. Bir oyun uygulamasının kaynakları diskten yüklemek için bir iş parçacığı, AI yapmak için bir iş parçacığı ve oyunu sunucu olarak çalıştırmak için başka bir iş parçacığı olabilir.

.NET / Windows işletim sisteminde, işletim sistemi bir iş parçacığına işlemci süresi ayırır. Her iş parçacığı, özel durum işleyicilerini ve çalıştığı önceliği izler ve işleyene kadar iş parçacığı bağlamını kaydetmek için bir yere sahiptir. İş parçacığı bağlamı iş parçacığının devam etmesi gereken bilgidir.

İpliklerle Çoklu Görev

İş parçacıkları biraz bellek kaplar ve bunları oluşturmak biraz zaman alır, bu nedenle genellikle çok fazla kullanmak istemezsiniz. Unutmayın, işlemci zamanı için yarışırlar. Bilgisayarınızda birden fazla CPU varsa, Windows veya .NET her bir iş parçacığını farklı bir CPU'da çalıştırabilir, ancak aynı CPU'da birkaç iş parçacığı çalışır, o zaman bir seferde yalnızca bir tane etkin olabilir ve iş parçacıklarını değiştirmek saati.

instagram viewer

CPU birkaç milyon talimat için bir iş parçacığı çalıştırır ve daha sonra başka bir iş parçacığına geçer. Tüm CPU kayıtları, geçerli program yürütme noktası ve yığını ilk iş parçacığı için bir yere kaydedilmeli ve daha sonra bir sonraki iş parçacığı için başka bir yerden geri yüklenmelidir.

Bir Konu Oluşturma

Ad alanında Sistem. Threading, iplik türünü bulacaksınız. Yapıcı iş parçacığı (ThreadStart) bir evre örneği oluşturur. Ancak, son zamanlarda C # kodunu kullanırsanız, yöntemi herhangi bir parametre ile çağıran lambda ifadesini iletme olasılığı daha yüksektir.

Hakkında emin değilseniz lambda ifadeleri, LINQ kontrol etmeye değer olabilir.

Oluşturulan ve başlatılan bir iş parçacığına bir örnek:

Sistem kullanma;
Sistem kullanarak. Diş;
ad alanı ex1
{
sınıf Programı
{
genel statik geçersiz Write1 ()
{
Konsol. Yaz ('1');
Konu. Uyku (500);
}
statik boşluk Ana (dize [] argümanları)
{
var task = yeni Konu (Write1);
görev. Başlat() ;
için (var i = 0; i <10; i ++)
{
Konsol. Yaz ('0');
Konsol. Yaz (görev. Yaşıyor? 'A': 'D');
Konu. Uyku (150);
}
Konsol. Anahtar okuma() ;
}
}
}

Tüm bu örnek konsola "1" yazmaktır. Ana iş parçacığı konsola 10 kez "0" yazar ve her seferinde diğer iş parçacığının hala Canlı veya Ölü olmasına bağlı olarak bir "A" veya "D" yazar.

Diğer iş parçacığı yalnızca bir kez çalışır ve "1" yazar. Write1 () iş parçacığındaki yarım saniyelik gecikmeden sonra, iş parçacığı ve Görev tamamlanır. Ana döngüdeki IsAlive artık "D" döndürüyor.

İş Parçacığı Havuzu ve Görev Paralel Kütüphanesi

Kendi iş parçacığınızı oluşturmak yerine, gerçekten yapmanız gerekmedikçe bir İş Parçacığı Havuzu kullanın. .NET 4.0'dan, Görev Paralel Kitaplığı'na (TPL) erişebiliriz. Önceki örnekte olduğu gibi, yine biraz LINQ'ya ihtiyacımız var ve evet, hepsi lambda ifadeleri.

Görevler İş Parçacığı Havuzu ancak kullanılan sayıya bağlı olarak iplikleri daha iyi kullanın.

TPL'deki ana nesne bir Görevdir. Bu, eşzamansız bir işlemi temsil eden bir sınıftır. İşleri çalıştırmaya başlamanın en yaygın yolu Görev'dir. Fabrika. Başlangıç ​​yeri:

Görev. Fabrika. StartNew (() => DoSomething ());

Burada DoSomething () çalıştırılan yöntemdir. Bir görev oluşturmak ve hemen çalışmamasını sağlamak mümkündür. Bu durumda, Görev'i şu şekilde kullanın:

var t = yeni Görev (() => Konsol. WriteLine ( "Merhaba"));
...
t. Başlat();

.Start () çağrılıncaya kadar iş parçacığı başlatılmaz. Aşağıdaki örnekte beş görev vardır.

Sistem kullanma;
Sistem kullanarak. Diş;
Sistem kullanarak. Threading. Görevler;
ad alanı ex1
{
sınıf Programı
{
genel statik geçersiz Write1 (int i)
{
Konsol. Yaz (i);
Konu. Uyku (50);
}
statik boşluk Ana (dize [] argümanları)
{
için (var i = 0; i <5; i ++)
{
var değeri = i;
var runningTask = Görev. Fabrika. StartNew (() => Yazma1 (değer));
}
Konsol. Anahtar okuma() ;
}
}
}

Bunu çalıştırın ve 03214 gibi bazı rasgele sırayla 0 ile 4 arasındaki basamakları alırsınız. Çünkü görev yürütme sırası .NET tarafından belirlenir.

Neden var value = i gerekli olduğunu merak ediyor olabilirsiniz. Kaldırmayı ve Write (i) 'yi çağırmayı deneyin, 55555 gibi beklenmedik bir şey göreceksiniz. Bu neden? Bunun nedeni, görevin oluşturulduğu zaman değil, görevin yürütüldüğü andaki i değerini göstermesidir. Yeni bir değişken döngüde her seferinde, beş değerin her biri doğru şekilde saklanır ve alınır.

instagram story viewer