shutterstock_170899481

 

Uzun bir aradan sonra herkese tekrar merhaba. Konuya geçmeden önce yazım ve imla kuralları hakkındaki hatalarım konusunda aldığım eleştirilere katıldığımı belirtmek isterim.  Bu konuda dikkat etmeye çalışıyorum. Hayatı boyunca yazılar, sınavlar ve kendini ifade edebilme konusunda her zaman sıkıntılar yaşamış bir insan olarak yaptığım ve yapacağım bu tür hatalardan dolayı herkesten özür dilerim.

C++ da thread ve process kavramları kaba taslak olarak paralel çalışan fonksiyon ve program parçalarıdır. Paralel olarak çalışmadan kastım aslında çok küçük zaman aralıklarıyla sıra sıra çalışırlar ama o zaman aralığı çok küçük olduğu için programcılar bu parçaları aynı anda çalışıyormuş gibi kabul eder. Aslında bakarsanız bu program parçaları kesmelerden oluşur. Kesmeler gömülü sistemlerin programlanmasında da çok fazlaca kullanılırlar.

Kesme dediğimiz şey daha çok donanımsal bir anlam taşır.  İşlemci mimarisi ile alakalıdır. İşlemci içerisinde bu kesme işlemini yerine getiren çeşitli register’ lar yani kaydediciler bulunur.  Ve yine işlemci içerisinde program komut satırlarını sayan sayıcılar vardır.  Bu sayaç ve register’lar sayesinde program komutlarını istediğiniz noktada keser ve işlemcinin istediğiniz noktadan programı okumaya devam etmesini sağlarsınız.  Bu olaya kaba taslak kesme deniyor.

Bir bilgisayar işlemcisi aynı anda birden fazla işlem yapamaz. Aynı anda sadece tek satır komut dizisi okuyabilir. Fakat şu anda kullandığımız gelişmiş bir bilgisayarları düşünecek olursak aynı anda birden fazla program çalıştırabiliyoruz. Biz kullanıcı olarak bu programların aynı anda çalıştığını düşünsek bile aslında işlemci bu programların komut dizilerini kesme kaydedicilerini ve program komut sayaçlarını kullanarak sıra sıra okur ve işler.   İşlemci hızı 2.4 ghz olan 64 bit bir işlemci düşünecek olursak. Bu işlemci 64 bitlik komut dizilerinin bir tanesini saniyenin sadece milyarda birinde okuyabilir.  Bu gerçekten ama gerçekten çok hızlı 🙂

 

Şimdi gelelim thread ve process kavramlarına. Yine kullandığınız bilgisayardan bir örnek verelim. Mesela bilgisayarınızda bir oyun çalıştırdığınızı düşünün. Ve bu oyunun yanında bir de medya oynatıcınızdan müzik açtınız. Oyun ve medya oynatıcınız birer process dir. Ve paralel olarak çalışırlar. Bu Process’ lerin yani program parçalarınında içerisinde paralel olarak çalışması istenen fonksiyonlar vardır.   Bu parçalar ise thread olarak adlandırılır.

Process’ler ve Thread’lar birbirine çok benzerler ama temel olarak birbirinden farklıdırlar.  Bir process, işlemci hızından ve hafızasından kendi başına bağımsız olarak kullanır. Bu arada, işlemci hızı ve hafıza gibi donanımsal terimleri programcılar, kaynak olarak adlandırırlar.  Ayrıca her process, kendine tahsis edilen ayrı bir adress alanında işlenir. Tabi ki bir işlemcinin sağlayabileceği kaynaklar da sınırlıdır. Yani bilgisayarınızda aynı anda bin tane program çalıştıramazsınız. Onların bir sınırı vardır. Sistem kaynaklarını sonuna kadar kullanmaya çalıştığınızda tabi ki bu durum, hem donanımsal olarak hem de yazılımsal olarak bir çok sorun ortaya çıkarır.

Eğer bir process yani çalıştırdığınız program üzerinden başka bir process yani program kaynaklarına erişmek istersem bu durumda “inter-process communications” adlandırılan ve pipes, files, sockets gibi işlemleri kullanmamız gerekir.

Her neyse, biraz da threadların genel yapısından bahsedip örnek bir program yazmak istiyorum. Thread’lar aynı adres alanını kullanan ve aynı process içerisindeki fonksiyonlardır.  Bir process içerisinde birden fazla thread olabilir.  Ve bu threadlar aynı kaynakları kullanırlar. Yani bir thread üzerinden diğer thread için kullanılan hafızaya erişebilirsiniz. Ama bu durum process’ler için aynı değildir.  Buna rağmen her bir thread kendi için farklı yığın veriler işlemci zamanı ve adres verileri kullanır.

Bu konu hakkında sayfalarca şey yazılıp çizilmiştir. Ama konunun özü o kadar da zor değil. Bunları kullanmadan da bir program yazabilirsiniz. Ama bunları kullandığınızda çok daha verimli, hızlı ve işlevsel programlar yazarsınız. Ben bu olayları virüs programları yazarken öğrendim.  İşin üstadı değilim ama kullanabiliyorum.  Yani olayı yılan hikayesine çevirmeye gerek yok.

C++ da thread oluşturmak için kullanılan bir çok kütüphane var. Ve thread bir çok farklı yolla oluşturulabilir. Aşağıdaki kullanılan yöntemlerden bir tanesi;

 

#include <stdio.h>
#include <pthread.h> // thrad oluşturma Kütüphanesi

static volatile int balance = 0;

void *deposit(void *param) // thread fonksiyonu
{
    char *who = param; 

    int i;
    printf("%s: begin\n", who);
    for (i = 0; i < 1000000; i++) {
        balance = balance + 1;
    }
    printf("%s: done\n", who);
    return NULL;
}

int main()
{
    pthread_t p1, p2; // iki thread tanımlanıyor
    printf("main() starts depositing, balance = %d\n", balance);
    pthread_create(&p1, NULL, deposit, "A"); // birinci thread için *deposit fonksiyonu çağrılıyor.
    pthread_create(&p2, NULL, deposit, "B"); //ikinci thread için de *deposit fonksiyonu çağrılıyor.

    // join fonksiyonu threadların komutları tamamen bitmesini beklemek için kullanılır. Yani birinci thread komutu bitmeden ikincisine geçilmez.
    pthread_join(p1, NULL);
    pthread_join(p2, NULL);
    printf("main() A and B finished, balance = %d\n", balance);
    return 0;
}

Bu programın çıkışı şöyle olacaktır;

main() starts depositing, balance = 0
B: begin
A: begin
B: done
A: done
main() A and B finished, balance = 1270850
----

Bu programı anlamakta zorlandıysanız şu program taslağına bir göz atın.

#include <stdio.h>
#include <thread.h>

using namespace std;

void task1() // birinci thread fonksiyonu
 {
 while(1)
	{
          ........
	}
 
 }
 void task2() // ikinci thread fonksiyonu
 {
	 while (true)
	 {
		 ......
	 }
 
 }
int _tmain() // ana thread fonksiyonu
{
            thread thread_1(task1); // birinci fonksiyon bir thread olarak tanımlanmış
	    thread thread_2(task2); //ikinci fonksiyon bir thread olarak tanımlanmış
		while (true)
		{

                      ...........

                }
}

Burada üç tane parelel olarak çalışan while döngüsü var. Tabi ki main() ana bloğun içerisinde kullanılan while döngüsü diğerlerine göre çok daha hızlı çalışacaktır.

CEVAP VER

Lütfen yorumunuzu giriniz!
Lütfen isminizi buraya giriniz