Thread (İş Parçacığı) Nedir

Esas olarak thread bir process’in aynı anda birden fazla işi yapmasını sağlayan yapı/yapılardır. Processlerin bünyesinde bir veya birden fazla thread bulunabilir. Buradaki en önemli ayrıntı ise bir thread aynı anda yalnızca tek bir iş yapabilir.

Bu bağlamda process içerisinde birden fazla thread çalıştırılmasına multi-threading denir. Paralel programming ise threadlerin çok çekirdekli işlemcilerin farklı çekirdeklerinde eş zamanlı olarak çalışmasıdır.

Threadleri User thread ve Kernel thread olmak üzere iki farklı türde inceleyeceğiz.

Process (Süreç-İşlem)

İşlemcide çalışan programlardı. Uygulamalar diskte çalışmaz halde bulunurken ise program olarak tanımlanırlar. Yani henüz çalıştıırılmamış olan uygulama(Word, Excel) bir programdır. Programlar çalıştırıldığında process olarak nitelendirilir. Process’ler çalışmaya tek thread ile başlarlar. Bu threadlere ise main thread denir. Diğer threadler ise programın çalışma sürecinde sistem fonksiyonları tarafından oluşturulmaktadır. Özetle process bir program çalıştığında yaptığı işlemdir.

Bir process içerisinde başka bir process oluşmasına ise child process denir.

Process ve Thread arasındaki farklar:

  • Thread process’lerin belirli bir segmentini işaret eder.
  • Oluşturma ve sonlandırma süreleri process’lere göre thread’ler için daha kısadır.
  • Process’ler birbirleri izole şekilde çalışırlar, thread’ler iseaynı bellek kaynağını paylaşrlar.
  • Thread’ler process’lere göre daha az kaynak tüketirler.
  • Bir process bloklanırsa başka bir process işlemini gerçekleştirmez. İlk process’in işini bitirmesi beklenir. Thread’lerde ise bir thread bloklansa dahi başka bir thread çalışabilir.
  • Processler’lerin ölçeklendirilebilrmesi için çok işlemcili yapıya ihtiyaç vardır. Buda process’lerdeki ölçeklendirmenin donanımsal olarak yapıldığını gösterir. Thread’lerde ise çok çekirdekli işlemcilerde birden fazla thread farklı çekirdeklerde çalıştırılabilir.

Paralelism: Birden fazla işlemci ya da çekirdekte aynı anda işlem yapılması anlamına gelmektedir.

Concurrency: Tek bir process üzerinde eş zamanlı olarak birden fazla operasyonun gerçekleştirilmesidir.

Thread Yaşam Döngüsü

İşletim sistemlerinde thread oluşturma işlemleri fonksiyonlar ile yapılır. Bu fonksiyonun ismi Windows’da ‘CreateThread’, Unix sistemlerde ise ‘phthread_create()’ isimli Posix foınksiyonu ile yapılmaktadır.

Thread’ler programlama dilleri kullanılarak kontrol edilebilirer. .Net ve Java dillerinde var olan Thread sınıfı ile thread yaratılabilir, başlatılabilir ve durdurulabilir.

Değiştirilmedikte Windows sistemlerde varsayılan olarak bir thread’in boyutu 1mb dir. Linux’da ise bu durum verisiyona göre değişmektedir.

Theread’lerin oluşturulmasından sonlandırılmasına kadar geçen süreçte farklı durumlara sahiptir.

Bir thread işletim sistemi veya programlama dilinin sunduğu fonksiyonlar aracılığıyla yaratıldığında ilk olarak NEW durumunda bekler. Eğer çalıştırılırsa Running durumuna geçer. Running/Runnable durumdaki bir thread, I/O isteğini gerçekleştirdiği esnada işlem bitene kadar Blocked durumunda kalır. Eğer thread geçici olarak durdurulmak istenirse belirtilen süre boyunca Waiting durumunda bekler ve süre bittiğinde tekrar Runnable durumuna geçer. Thread sonlandırıldığında ise Terminated durumuna geçer.

Thread’ler farklı yollar ile sonlandırılabilirler. Örneğin thread’in çalıştırdığı işlem/fonksiyon ttamamlanırsa thread’de sonlanmış olur. Aynı zamanda main thread sonlanırsa process’e ait tüm thread’ler de sonlanmış olur. Bir thread kendisini veya farklı bir thread’i sonlandırabilir. Thread’lerin kendilerini sonlandırabilmeleri için Windows sistemlerde bu işlem ExitThread API fonksiyonu ile yapılırken UNIX işletim sistemlerinde ise pthread_exit() isimli POSIX fonksiyonu ile sonlandırma işlemi gerçekleştirilebilir. Bir thread’in başka bir thread’i sonlandırması için ise Windows’ta TerminateThread fonksiyonu yer almakta, UNIX sistemlerde ise pthread_cancel() isimli POSIX fonksiyonu bulunmaktadır.

Kernel Thread

Process içinde yer alan ve kernel seviyesinde yönetilen bir thread türüdür. İşletim sistemi tarafından zamanlanırlar. Bu thread türündeki thread’ler sadece kernel modda çalışmaktadır. Yazılım geliştiricilerin bir kernel eklentisi ya da cihaz driver’ı yazmıyorlarsa bu thread türüne direkt erişimi yoktur. Yeni bir kernel thread yaratmak için kthread_create() ya da kthread_run() isimli fonksiyon kullanılır.

Process ve kernel thread arasındaki farklar;

  • Kernel thread’ler kernel seviyesinde yönetilmektedirler.
  • Process’ler arası bir bilgi paylaşımı yoktur. Kernel thread’ler ise birbirleri arasında adres uzayı (address space) bilgisini paylaşırlar.
  • Kernel thread’ler işletim sistemi tarafından zamanlanır.
  • Process’ler askıya alınabilirken, kernel thread’ler askıya alınamazlar.

User Thread

Kullanıcı tarafından yönetilmektedir ve kernel desteği bulunmamaktadır. Kernel, user thread’lerden habersizdir. Genelde bir uygulama geliştirildiğinde kullanılan thread’ler, user thread olarak geçmektedir. Örnek olarak Java ve .Net içerisinde yer alan Thread sınıfı user thread’lere örnek olarak verilebilir. CPU yalnızca Kernel thread çalıştırabildiği için user thread bir kernel thread’e eşlenerek çalıştırılır.

User thread ve Kernel thread arasındaki farklar;

  • User thread’ler kullanıcılar tarafından Thread kütüphanelerinin sağladığı fonksiyonlar ile yönetilir. Kernel thread ise işletim sistemi tarafından yönetilmektedir.
  • İşletim sistemleri user thread’ler ile alakalı herhangi bir düzenleme yapmaz.
  • User thread’in implementasyonu kernel thread’e göre daha kolaydır.
  • User thread’lerde bir thread sistem çağrılarını bloklayan bir operasyon gerçekleştirirse tüm process bloklanır. Kernel thread’lerde ise bir thread bloklasa bile farklı bir thread çalışmasına devam edebilir.

Kernel thread’lerde bir thread bloklansa bile başka bir thread’in çalışmaya devam etmesinin sebebi Kernel’ın bunu biliyor olması. Örnek olarak, thread A ve thread B isminde iki farklı thread’imiz var. Thread A sistemi bloklasa bile kernel, thread B’nin varlığından haberdar olduğu için beklemeden thread B’yi çalıştırabilir.

User thread’lerde ise; bahsedilen gibi kernel, kullanıcı tarafından oluşturulan thread’lerden habersizdir. Bu thread’leri sadece uygulama bildiği için thread A sistemi blokladığında kernel thread B’yi çalıştıramaz.

Multi Thread Modeller

One to One (1:1) Model

Bu modelde her bir user thread, bir kernel thread ile eşleşmektedir ve thread yönetimi kernel seviyesinde yapılır. Buradaki user thread’lerden herhangi biri sistem çağrılarını blokladığında diğer thread’ler çalışmaya devam edebilir, böylece tüm process bloklanmaz. Concurrency açısından M:1 (Many to One) modele göre daha avantajlıdır. Ancak bu modelin dezavantajı ise daha çok efor gerektirmesi ve thread yönetiminin daha yavaş olmasıdır. Çoğu implementasyonunda yaratılabilecek thread sayısı limitlendirilmiştir.

Many to One (M:1) Model

Bu modelde birden fazla user thread tek bir kernel thread’e maplenmiş durumdadır. Thread yönetimi thread kütüphanesi aracılığıyla user space’te yapılmaktadır. Eğer bir user thread sistem çağrılarını bloklayacak bir operasyon gerçekleştirirse tüm process bloklanır. Birim zamanda tek bir user thread Kernel’a erişebileceğinden dolayı diğer threadler çalışamazlar.

Many to Many (M:M) Model

Bu modelde ise user thread sayısı kadar kernel thread’e eşler. Bu modelde uygulamanın gerektiği kadar user thread yaratılabilir. Yaratılan user thread’lere karşılık gelen kernel thread’ler çok işlemcili makinelerde paralel olarak çalıştırılabilir. Herhangi bir thread bloklansa bile Kernel başka bir thread’i çalıştırabilir bu sayede tüm process bloklanmaz.

Hyper-threading (Simultaneous Multithreading-SMT)

Intel tarafından geliştirilmiş ve ilk kez Şubat 2002 tarihinde Xeon işlemcilerde kullanılarak hayatımıza giren Hyper-threading teknolojisi işlemci kapasitesini daha iyi kullanır ve bunu yapabilmek için ise fiziksel bir işlemci çekirdeğini iki sanal işlemci çekirdeği gibi gösterir. Her sanal işlemci diğer sanal işlemcilerden ve fiziksel işlemcilerden bağımsız olarak hareket eder. Özetle Hyper-Threading tek bir işlemci çekirdeğinin, 2 farklı çekirdek gibi çalışabilmesini sağlar.

CPU Nasıl Çalışır

CPU, Kontrol Bİrimi(Control Unit) ve Aritmetik/Mantık Birimi(Aritmetic/Logic Unit) olmak üzere içerisinde iki adet bölüm mevcuttur. Kontrol birimi elektrik sinyalleri ile direkt olarak bilgisayar sistemine çalıştırılması gerekenleri aktarır. Kontrol birimi herhangi bir mantıksal ya da aritmetik yönergeleri taşımaz onları çözerek bilgisayar sisteminin diğer parçalarına aktarır. Aritmetik/mantık birimi tüm bu aritmetik ve mantıksal operasyonları taşıma görevini üstlenir.

Adımlarsak eğer:

1- Kontrol birimi bilgisayar belleğinden talimetları alır.

2- Bunları okuyup anlamlandırarak aritmetik/mantık birimine aktarır. 1. ve 2. adım birleşik olarak talimat/yönerge zamanı (instruction time) ya da I-time olarak isimlendirilir.

3- Aritmetik/mantık birimi aritmetik ve mantıksal yönergeleri taşır. Bu kısım aynı zamanda aritmetik/mantık biriminin gerçekten operasyonu gerçekleştirdiği adımdır.

4- Aritmetik/mantık birimi sonucu bellekte ya da register’da tutar. 3. ve 4. adım birleşik olarak çalışma zamanı (execution time) ya da E-time olarak isimlendirilir.

Bu adımlar işlemci hızına ve farklı parametrelere bağlı olarak saniyeler içerisinde gerçekleşmektedir. Eğer işlemci yetersiz ise sistemde yavaşlamalar ve/veya darboğazlar yaşanır. Tam bu noktada Hyper-threading devreye giriyor. Hyper-threading her bir işlemci çekirdeğinin aynı anda iki işlem yapmasını sağlıyor. Bu da daha efektif işlemci kullanımı ve performansına kapı aralıyor. Hyper-threading kernel içerisinde işlemciyi birden fazla işlemi aynı anda yapmak için kandırıyor denilebilir. Hyper-threadingişlemcinin farklı bölgelerini paralel bir biçimde kullanarak bir thread’in ihtiyaç duymadığı alanda başka bir thread’i çalıştırıyor. Ancak her iki thread’in aynı işlemci alanına ihtiyaç duyması halinde birinin diğerini beklemesi gerekiyor. Intel’in tanımına göre Hyper-threading aktif olduğunda her fiziksel çekirdek için 2 execution context ortaya çıkarmaktadır. Bu da en temel anlamda CPU zamanlayıcısının birden fazla işi tek çekirdekte çalıştırabilmesini sağlıyor.

%100 CPU kullanımı, fiziksel alan kapasitesinin yetersizliğini değil işlemcinin başka bir thread’i zamanlayamadığının (scheduling) göstergesidir.

Kavramlar

Race Condition

Birden fazla thread ya da process’in aynı anda aynı kaynağa erişmeye ve durumunu değiştirmeye çalışması sonucunda ortaya çıkan durumdur.

Critical Section

Birden fazla thread ya da process tarafından paylaşılan kod alanlarına critical section adı verilir. Buradaki kontrolü sağlamak için Mutex, Semaphore, Monitor, Lock gibi yapılar kullanılmaktadır. 

CPU Scheduling

İşlemcinin çalıştırılmaya hazır process’ler arasından seçim yaparak seçilen process’in çalıştırması işlemidir. İki farklı scheduler tipi mevcut birisi Short-term scheduler diğeri ise Long-term scheduler olarak isimlendirilir.

CPU Scheduling Algoritmaları

6 adet zamanlama (scheduling) algoritması vardır.

  1. First Come First Serve (FCFS)
  2. Shortest-Job-First (SJF) Scheduling
  3. Shortest Remaining Time
  4. Priority Scheduling
  5. Round Robin Scheduling
  6. Multilevel Queue Scheduling

Process Control Block (PCB)

İşletim sistemlerinin process’e ait tüm bilgileri saklamak için kullandığı veri yapısıdır. Her process’in bir PCB’si bulunur. PCB içerisindeki bilgiler process her durum değiştirdiğinde güncellenir.

Context Switch

Process’ler işlemcide sadece kendilerinin var olduğunu düşünen ve herhangi bir etkide bulunulmadığı takdirde tüm kaynağın ve adres uzaylarının kendisinin kullanımında olduğunu düşünen yapılardır. Bir process’in işlemci üzerinde çalışma zamanı dolduğunda o anki durumunu belleğe kaydedip işlemciden temizleyerek bir sonraki process’in çalıştırılması gerekli. Process durumunun kaydedilip, işlemciden temizlenmesi, bir sonraki process’in çalıştırılması ve zamanı geldiğinde  process’in kaydedilen durumunun tekrar yüklenerek kaldığı yerden çalıştırılması işlemine context switch adı verilmektedir. Process bu süreçte işlemci üzerinden hiç ayrılmadığını düşünerek çalışmaya devam eder.

Symmetric Multiprocessing

Context switch sayısını azaltmanın yanı sıra işlemci üzerinde process’ler için daha fazla çalışma zamanı oluşturmanın bir diğer yolu ise Symmetric Multiprocessing’dir (SMP). SMP ile işletim sistemi aynı anda iki farklı process’i farklı işlemcilerde çalıştırabilir. Elbette bu process’ler iki işlemci olduğunda da sıra beklemek zorundadır. Ancak hizmet veren iki işlemci olduğundan ve çalışma süresi arttığından dolayı process’lerin çalışma süresi daha fazla ve bellekte beklediği süre daha az olacaktır. SMP iki ya da daha fazla işlemciye sahip bir işletim sisteminde main memory (MM) adı verilen, ortak bellek alanına sahiptir. Her işlemcinin veriye erişimi hızlandırmak ve veri trafiğini azaltmak için kendine ait önbelleği bulunmaktadır.

Kaynak: Thread Nedir? Detaylı Bir Thread İncelemesi | Devnot

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir