C# ile Multi Thread Çalışma -- Çok Kanallı Çalışma

Posted on 2015-11-26 by Burak Hamdi TUFAN
General Programming
C# ile Multi Thread Çalışma -- Çok Kanallı Çalışma
Herkese merhabalar. Bu yazıda sizlere C# ile nasıl multi Thread çalışmayı anlatacağım. İlk olarak Multi Thread ne demektir onu anlatacağım. Sonra bir örnek yaparak konuyu pekiştireceğiz.

Multi thread çok kanallı çalışma anlamına gelir. yani yapılacak olan bir işlemi parçalara bölüp aynı anda kaç parçaya böldüysek yapmaktır. İşçi havuz problemlerindeki gibi bir işi tek bir işçi yapacağına birden fazla işçinin yapmasını sağlayacağız.

Bu şekilde işlemlerimiz iki kat üç kat hızlanacaktır. Çünkü birden fazla işlem parrçacığı ile işlem yapmış olacağız.

Bu işlem için programımıza ilk olarak Thread kütüphanesini eklememiz gerekmektedir.

using System.Threading;
using System.Threading.Tasks;

Yukarıdaki kütüphaneleri ekledikten sonra kodlama kısmına geçebiliriz. İlk olarak thread ile çalışacak fonksiyonlarımızı belirtmeliyiz. Yani thread çalıştırıldığında hangi fonksiyonumuz çalışacak bunu hazırlamamız gerekmektedir.


 public void say1()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(i.ToString());
            }
        }

        public void say2()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(i.ToString());
            }
        }

        public void say3()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(i.ToString());
            }
        }

Yukarıdaki gibi üç tane fonksiyon hazırladık ve ve bu fonksiyonları ayrı ayrı thread lar ile çağıracağız ve çıktılara bakacağız. Program çıktısından threadların işlemi yapma şekline bakacağız. Şimdi Threadların nasıl çalıştırıldığına bakalım...


Thread tread1= new Thread(say1);
      treat1.Start();

      Thread tread2= new Thread(say2);
      tread2.Start();

      Thread tread3= new Thread(say3);
      tread3.Start();

Yukarıdaki kod bloğunda ise Threadlarımızı oluşturduk ve başlattık. Gördüğümüz gibi threadlarımız oluşturduk ve içerisinde hangi fonksiyonun çalışacağını belirledik Bu şekilde fonksiyonu thread üzerine bindirdik ve çalıştırdık.


1
2
1
2
3
4
1
2
6
7
3
4
5
Gerisi getirmedim. Gördüğünüz gibi threatların çalışma sırasına göre farklı Çıktılar alabiliyoruz.

Peki Threadların içerisinde aynı fonksiyonu çalıştıramazmıyız.

Tabiikide çalıştırabiliriz. Farklı Threadlar içerisinde aynı fonksiyonu çalıştırabiliriz.Aşağıda bununla ilgili bir örnek yapalım.

 void islem()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(i.ToString());
            }
        }

        Thread tread1 = new Thread(islem);
        tread1.Start();

        Thread tread2 = new Thread(islem);
        tread2.Start();

        Thread tread3 = new Thread(islem);
        tread3.Start();

Yukarıdaki kod bloğunda gördüğümüz üzere aynı fonksiyonu üç farklı thread ile üç defa çalıştırmış olduk. Bu şekilde fonksiyonun yapacağı toplam işi üçe bölerek yaptırmış olduk ve işlemi daha hızlı bir şekilde yaptırmış olduk. Programın çıktısı yine önceki örneğin çıktısına benzer olacaktır.

Birde dikkat edersek fonksiyonun içerisine değişken değeri göndermeden bu işlemi yaptık. Ama atıyorum 300.000 tane değişken değeri olacak olan bir sonuç almak istiyoruz. Peki bunu nasıl yapacağız. Yukarıdaki şekilde dikkat edin değişkenlerimizi Thread ile fonksiyona gönderemiyoruz.

Aşağıda yazacağımız fonksiyon örneği ile fonksiyon içerisine değişken göndererek çalıştıralım.

 void fonksiyon(int bas,int son)
        {
            for (int i = bas; i < son; i++)
            {
               Console.WriteLine(i.ToString());
            }
        }

        Thread tread1 = new Thread(() => fonksiyon(0,10));
        tread1.Start();

        Thread tread2 = new Thread(() => fonksiyon(10,20));
        tread2.Start();

Yukarıdaki örnekte fonksiyon içerisine değişken gönderdir. Değişken göndererek çalışmasını sağladık. Programın çıktısı ise yaklaşık olarak aşağıdaki şekilde olacaktır.


1
2
10
11
12
3
14
4

Yukarıdaki programın çıktısının geri kalanını yazmadım ama aşağı yukarı bu şekilde çıkacaktır. Birde farklı bir yöntem olarak delegate nesnelerini kullanarak başlatma var. Yani kodlarımızı bir delegate ye eşitliyoruz ve o şekilde çalıştırıyoruz Aşağıda ise bunun ile ilgili bir örnek verdim onuda inceleyelim


ThreadStart ts = delegate
{
      for (int i=0; i<10; i++)
      {
           for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(i.ToString());
            }
           //kodlar buraya gelecek bu şekildede fonksiyonumuzu buraya yazarak çalıştırabiliriz
      }
};
new Thread(ts).Start();

Eğer isterseniz şimdi son bir örnek yapalım ve yazımızı bitirelim.

Şimdi girilen bir sayıya kadar olan çift sayıları bulduran bir programı multi thread mantığı ile yapalım.

int sayac = 0;
int girilen = Convert.ToInt32(Console.ReadLine());


        void kontrol(int bas,int son) //kontrol edecek olan fonksiyonumuz
        {
            for (int i = bas; i < son; i++)
            {
                if (i % 2 == 0)
                {
                    sayac++;
                    Console.WriteLine(i.ToString());
                }
            }
        }

        int thread_sayisi = girilen / 1000 + 1;

        for (int i = 0; i < thread_sayisi; i++)
                {
                    Thread treat = new Thread(() => kontrol(thread_sayisi*i,thread_sayisi*(i+1));
                    treat.Start();
                }

Yukarıda thread_sayisi ile sayıları biner biner kontrol ettireceğiz kaç tane sayı giriyorsa onu 1000 sayısına bölecek ve işlemi o kadar thread ile yaptıracak. For döngüsü içerisinde yukarıdaki gibi fonksiyonlarıda yazabiliriz.

Göründüğü gibi for döngüsü içerisinde istediğimiz kadar thread oluşturduk ve başlattık. Bu şekilde işlem hızını kulanıcının girdiği değere göre yaptırdık. Bu şekildede normal olarak yaptığımızda 10 saniyede bitecekse işlem 2 , 3 saniyeye kadar indirdik.

Son olarak şunuda ekleyerek yazımızı bitirelim

Bir elin nesi var iki elin sesi var mantığı ile Multi Thread kulanımı programlarımızda ağır işlemler için çok büyük hız kazanmamıza yardımcı olacaktır. Çünkü aynı işlemi birden çok işçiye yaptırmış oluyoruz.

Bu yazımızda bu kadar -- Takipte Kalın

İyi Çalışmalar

Burak Hamdi Tufan


Tags
Share this Post
Send with Whatsapp