Multithreading Programlama

 

Öncelikle Yüksek Lisans öğrencim “Melike Bektaş”e teşekkürler. Bu bölümde Python ortamında multithread bir kod oluşturmayı göreceğiz.

Bir işletim sistemi üzerinde herhangi bir dil ile kodlanmış ve bir compiler (derleyici) ile derlenmiş ve daha sonra hafızaya yüklenerek işlemcide çalıştırılan programlara process denir. Kısacası bir programın çalışan hali processtir.

Threadler ise processlerin içerisinde yer alan eş zamanlı olarak çalışabilen iş parçacıklarıdır. Yani threadler sayesinde kodlarımızı ardaşıl olarak yürütmek yerine eş zamanlı olarak yürütebiliriz.

Multithreading, çoğu yazılım dili tarafından desteklenen temel programlama prensibidir ve bir programda aynı zamanda birden fazla işin yapılabilmesini sağlamaktadır. Yani bir kod parçası bir işlemi gerçekleştirirken aynı anda ona paralel olarak bir başka kod parçasının da çalışması demektir. Multithread yapısında olmayan programlar, main thread isimli tek bir thread üzerinden yürütülürler.

Thread kullanmak;

  • Kaynak paylaşımı
  • Daha az bekleme süresi
  • Daha verimli donanım kullanımı

gibi faydalar sağlamaktadır.

1. Multithreading Modülü

Python dilini kullanarak threadler ile ilgili uygulamalar geliştirmek istiyorsak aşağıdaki iki modülden birisini import etmemiz gerekmektedir. Bu modüller;

  • <thread>
  • <threading>

modülleridir.

<thread> modülü python 3 ile birlikte <_thread> olarak değişmiştir. <_thread> ve <threading> modülleri arasındaki temel fark <threading> modülünün nesne dayalı programlama prensibini desteklemesidir.

_thread modülünü kullanarak;

Yukarıda yer alan kodda thread ile ilgili fonksiyonları kullanabilmek için ilk önce _thread modülünü import ettik.

_thread.start_new_thread(f,(“thread-1”,)) ile yeni bir thread tanımladık ve threade hedef olarak f fonksiyonunu parametre olarak “thread-1”i verdik ve start ile çalıştırdık. Fonksiyon ile çalışan threadi 7 kere ekrana yazdırdık.

threading modülünü kullanarak;

Yukarıdaki kodda ilk olarak threading modülünü import ettik.

t1 = threading.Thread(target=f,args = (“thread-1”, )) kodu ile t1 adında bir thread oluşturduk, threade hedef olarak f fonksiyonunu parametre olarak da “thread-1”i verdik. Start() komutuyla threadi çalıştırdık. İki threadi de ekrana 7 kere yazdırdık. Yukarıdaki uygulamalarda threadlerin eş zamanlı olarak çalıştıkları, thread-1 bitmeden thread-2’ninde başladığı görülmektedir.

Yukarıda yer alan kodda ilk olarak _thread ve date modülünü import ettik. İlgili modülleri import ettikten sonra try bloğu içerisinde iki tane thread tanımladık, tanımladığımız threadlere hedef olarak print_time fonksiyonunu (threadin yapacağı iş) parametre olarak da “thread-1” ve 1’i verip çalıştırdık. Ekran çıktısı yukarıdaki gibidir. Thrad-1 1 saniye bekleme süresi ile ekrana tarihi ve sistemin saatini yazdırmaktadır. Thread-2 ise 3 saniye bekleme süresi ile ekrana tarihi ve sistemin saatini yazdırmaktadır.

Threadler ile faktöriyel hesabı;

Thread’ler çok kısa olduğunda yukarıdaki gibi karışmadan çalışabilir.

2. Threading Modülünün Metotları

<threading> modülünün <_thread> modülünden nesneye dayalı programlama prensiblerini desteklemesi yönünden farklıdır. Bunun yanında <threading> modülü <_thread> modülünün tüm metodlarını içerir ve <_thread> modülüne ek bazı metodları da destekler. Bu metodlar aşağıdaki gibidir:

  • threading.activeCount() : Aktif olarak çalışan thread sayısını geri döndürür.
  • threading.enumerate() : Aktif olarak çalışan threadlerin listesini geri döndürür.
  • threading.main_thread() : Main threadi geri döndürür.
  • threading.get_ident() : Threadin tanımlayıcısını (identifier) geri döndürür.

3. Thread Sınıfı Metotları

Thread sınıfının metodları aşağıdaki gibidir.

  • run() : Threadin etkinliğini yaptığı işi temsil eder.
  • start() : Threadin yapacağı işi, etkinliğini başlatır. run() metodunun çalıştırılmasını sağlar.
  • join([time]) : Thread sonlanana kadar bekler.
  • isAlive() : Threadin hala çalışıp çalışmadığını kontrol eder. True, false değer döndürür.
  • getName() : Threadin adını döndürür.
  • setName() : Threadin adını set eder.

Yukarıda yer alan örnekte Thread sınıfını kullandık. Oluşturmuş olduğumuz myThread isimli sınıf Thread sınıfından miras almıştır.

def __init__(self, threadID, name, counter): satırı ile bu sınıfa ait bir constructor oluşturduk ve bu constructor içerisinde ilk değer ataması gerçekleştirdik.

thread1 = myThread(1, “Thread-1”, 1) satırı ile yeni bir thread tanımladık ve bu threadi thread1.start() satırı ile çalıştırdık. Start() metodu ile run() metodu tetiklendi ve thread asıl gerçekleştirmesi gereken işi bu şekilde gerçekleştirdi.

Ayrıca, kodun son bölümünde thread’ler çalışırken thread ismini değiştirdik.

4. Thread’lerin Senkronizasyonu

Thread senkronizasyonu kilit mekanizması sağlanır. Lock() metodu çağırılarak bir kilit oluşturulur. Bu metod threadlerin eş zamanlı olarak çalışmasını engelleyen bir mekanizmadır. Yani bir thread sonlanır ve diğer thread çalışmasına ondan sonra devam eder. Kilit acquire() fonksiyonu ile aktif hale gelir, release() fonksiyonu ile serbest bırakılır.

Diğer sayfada bulunan ekran çıktısında da görüldüğü gibi thread-1 bittikten sonra thread-2 çalışmış ve sona ermiştir. Senkronizasyon işlemi başarı ile sona ermiştir.

Kaynaklar:

  • “Python For Learners” 114 – 125