C#’ın multi thread sistemi Thread sınıfı üzerine kurulmuştur. Thread sınıfı sealedtır. Yani kalıtım yoluyla aktarılamaz.
Bir thread oluşturma
using System; using System.Threading; namespace multiThread { class PersonalThread { public int sayac; public Thread myThread; //constructor public PersonalThread(string name) { sayac = 0; myThread = new Thread(new ThreadStart(this.run)); myThread.Name = name; myThread.Start(); } public void run() { Console.WriteLine(myThread.Name + "başladı"); do { Thread.Sleep(500); Console.WriteLine("sayac:" + sayac); sayac++; } while (sayac < 5); Console.WriteLine(myThread.Name + " bitti"); } } }
namespace multiThread { class Program { static void Main(string[] args) { PersonalThread thread1 = new PersonalThread("thread 1"); } } }
Çıktı:
thread 1başladı
sayac:0
sayac:1
sayac:2
sayac:3
sayac:4
thread 1 bitti
Birden fazla thread oluşturma
Aşağıdaki şekilde değiştirip çalıştırdığımızda iki çocuk kanal aynı CPU’yu paylaşmaktadır. İşletim sistemine ve bazı çevresel etmenlere bağlı olarak çıktılarımız farklılık gösterebilir.
namespace multiThread { class Program { static void Main(string[] args) { PersonalThread thread1 = new PersonalThread("thread 1"); PersonalThread thread2 = new PersonalThread("thread 2"); } } }
Çıktı:
thread 1başladı
thread 2başladı
thread 2sayac:0
thread 1sayac:0
thread 2sayac:1
thread 1sayac:1
thread 2sayac:2
thread 1sayac:2
thread 2sayac:3
thread 1sayac:3
thread 2sayac:4
thread 2 bitti
thread 1sayac:4
thread 1 bitti
Bir threadın ne zaman sona ereceğini belirlemek
Bir threadın ne zaman sona ereceğini bilmek önemlidir. C# ta “Join()” kullanarak çağrıldığı kanalın sona erip ermediğini öğrenebiliriz. Örnek kod ve çıktısı aşağıdadır.
using System; namespace multiThread { class Program { static void Main(string[] args) { PersonalThread thread1 = new PersonalThread("thread 1"); PersonalThread thread2 = new PersonalThread("thread 2"); PersonalThread thread3 = new PersonalThread("thread 3"); thread1.myThread.Join(); Console.WriteLine("thread1 join"); thread2.myThread.Join(); Console.WriteLine("thread2 join"); thread3.myThread.Join(); Console.WriteLine("thread3 join"); } } }
Çıktı:
thread 1başladı
thread 2başladı
thread 3başladı
thread 3sayac:0
thread 1sayac:0
thread 2sayac:0
thread 3sayac:1
thread 1sayac:1
thread 2sayac:1
thread 3sayac:2
thread 1sayac:2
thread 2sayac:2
thread 3sayac:3
thread 1sayac:3
thread 2sayac:3
thread 3sayac:4
thread 3 bitti
thread 1sayac:4
thread 1 bitti
thread1 join
thread 2sayac:4
thread 2 bitti
thread2 join
thread3 join
Thread öncelikleri
Her thread bir önceliğe sahiptir. Bir threadın önceliği CPU’da ne kadar çalışacağını belirler. Düşük öncelikli threadler daha az CPU zamanı harcarlar. Burada dikkat etmemiz gereken şey ise bir threadın CPU’da harcayacağı zaman sadece thread önceliğine bağlı değildir. Örnek vermek gerekirse CPU’da çalışan yüksek öncelikli bir thread bir kaynağı bekliyorsa(klavye girişi,IO işlemleri) o thread bloke edilecek daha düşük öncelikli başka bir thread çalışacaktır. Böylece düşük öncelikli bir thread daha yüksek öncelikli bir threade göre daha fazla CPU zamanı kullanmış olacaktır. C# dilinde bir thredin önceliği ThreadPriority özelliği ile ayarlanabilir.
Örnek üzerinde inceleyelim
using System; using System.Threading; namespace multiThread { class PersonalThread { public int sayac; public Thread myThread; static bool durdur = false; static string simdikiThreadAdi; //constructor //dikkat ederseniz önceki örneklerdeki gibi thread constructorda baslatilmadı public PersonalThread(string name) { sayac = 0; myThread = new Thread(new ThreadStart(this.run)); myThread.Name = name; simdikiThreadAdi = name; } public void run() { Console.WriteLine(myThread.Name + "başladı"); do { sayac++; if (simdikiThreadAdi != myThread.Name) { simdikiThreadAdi = myThread.Name; // Console.WriteLine("calisan thread " + simdikiThreadAdi); } } while (durdur == false && sayac < 1000000); durdur = true; Console.WriteLine(myThread.Name + " bitti"); } } }
using System; namespace multiThread { class Program { static void Main(string[] args) { PersonalThread thread1 = new PersonalThread("Yuksek öncelik"); PersonalThread thread2 = new PersonalThread("Düşük öncelik"); //thread önceliklerinin ayarlanması thread1.myThread.Priority = System.Threading.ThreadPriority.Highest; thread2.myThread.Priority = System.Threading.ThreadPriority.Lowest; thread1.myThread.Start(); thread2.myThread.Start(); thread1.myThread.Join(); thread2.myThread.Join(); Console.WriteLine(thread1.myThread.Name +"sayacı " + thread1.sayac); Console.WriteLine(thread2.myThread.Name + "sayacı " + thread2.sayac); } } }
Çıktı:
Yuksek öncelikbaşladı
Düşük öncelikbaşladı
Yuksek öncelik bitti
Düşük öncelik bitti
Yuksek önceliksayacı 1000000
Düşük önceliksayacı 980470
Gördüğümüz gibi yüksek öncelikli thread CPU’da daha fazla zaman kullandı.
Threadleri askıya almak ve sürdürmek
Kanalı askıya almak için Thread.Suspend() sürdürmek için ise Thread.Resume() kullanılır.
using System; using System.Threading; namespace multiThread { class PersonalThread { public int sayac; public Thread myThread; //constructor public PersonalThread(string name) { sayac = 0; myThread = new Thread(new ThreadStart(this.run)); myThread.Name = name; myThread.Start(); } public void run() { Console.WriteLine(myThread.Name + "başladı"); do { Thread.Sleep(500); Console.WriteLine("sayac:" + sayac); sayac++; } while (sayac < 10); Console.WriteLine(myThread.Name + " bitti"); } } }
using System; using System.Threading; namespace multiThread { class Program { static void Main(string[] args) { PersonalThread thread1 = new PersonalThread("thread1"); Thread.Sleep(2000); thread1.myThread.Suspend(); Console.WriteLine(thread1.myThread.Name + " durduruldu."); Thread.Sleep(1000); thread1.myThread.Resume(); Console.WriteLine(thread1.myThread.Name + " devam ettirildi."); } } }
Çıktı:
thread1başladı
sayac:0
sayac:1
sayac:2
thread1 durduruldu.
thread1 devam ettirildi.
sayac:3
sayac:4
sayac:5
sayac:6
sayac:7
sayac:8
sayac:9
thread1 bitti
Bir yanıt yazın