Process ve Thread Nedir ?

 Process Kavramı

Bilgisayarlarımızda kullanmış olduğumuz programlar genellikle diskte veya geçici (non-volatile memory) diskte saklanır. Yazılmış olan kodlar makine diline (0-1) interpreter veya C gibi dillerdeki gibi direkt compile edilirler. Dilden bağımsız olarak sonuçlar aynıdır, bir program çalıştırıldığında, binary olarak belleğe yüklenir. Bilgisayarın CPU’su yalnızca binary komutları algılar.

Kullanmış olduğunuz işletim sistemlerinde process, thread gibi kavramları mutlaka görmüşsünüzdür. Bilgisayarımızın yürütmüş olduğu programların çalışması için belleğe ve çeşitli işletim sistemi kaynaklarına ihtiyaçları vardır.

“Process” ihtiyaç duyulan tüm kaynaklar ile birlikte belleğe yüklenmiş bir programdır.
Her bir sürecin (process) ihtiyaç duyduğu temel kaynaklar; registers, counter ve stacktir.
Bir register kayıt, talimat, saklama adresi veya işlemin ihtiyaç duyduğu türden verileri tutabilir.
Counter ise bazı yerlerde “instruction pointer” olarak karşınıza çıkabilir, bir bilgisayarın program sırasında nerede olduğunu izler.
Stack (yığın) bir bilgisayar programının etkin alt rutinleri hakkında bilgi depolayan ve işlem için çalışma alanı olarak kullanılan bir veri yapısıdır.
C derslerinden tanıdık gelen bir kavram olan dinamik olarak ayrılan memorylerde (dynamically allocated memory) “heap” olarak adlandırılır.

Her processin ayrı bir bellek adresi vardır, bu da her işlemin bağımsız olarak çalıştığı ve diğer işlemlerden izole edildiği anlamına gelir. Yani bir process çalışırken yalnızca kendini çalışıyor zanneder. Diğer işlemlerde paylaşılan verilere doğrudan erişemez.

İşlemlerin bu bağımsızlıkları değerlidir, çünkü işletim sistemi süreçleri izole etmek için elinden gelenin en iyisini yapmaya çalışır, böylece bir işlemdeki bir sorun başka bir işlemi bozmaz veya hasara neden olmaz. Örneğin, bir uygulamanız bozulduğunda (crash) diğer uygulamaları etkilemeden o uygulamayı sonlandırabilirsiniz.
Process kavramını öğrendikten sonra şimdi de thread kavramını inceleyelim.

Threads

Bir thread, process içindeki yürütme birimidir. Bir process, sadece bir threadden oluşabildiği gibi bir çok threadden de oluşabilir.

  • Threadler hafif işlerdir.
  • Threadler ait oldukları processlerin belleklerini kullanırlar.
  • Threadlar arası iletişim, processler arası işlemden daha hızlıdır.

Bir process başlatıldığında, bellek ve kaynaklar atanır. Her bir thread bu belleği ve kaynakları paylaşır.

Tek threadli processlerde, process ve thread birdir, aynıdır ve yalnızca bir tek şey yapılabilir.

Çoklu threadli processlerde, bir process aynı zamanda birden daha fazla şeyi yapabilir.

Thread In C

Her thread ThreadID adında bir ID ile tanımlanır
Thread ID Process ID’den oldukça farklıdır. Thread ID’ler process içinde benzersiz (unique) iken, processler tüm sistemde eşsizdir.
Thread ID pthread_t şeklinde tanımlanmıştır.

Bir thread yaratabilmek için,
pthread.h  adındaki header file içerisinde bulunan pthread_create metodunu çağırılmalıdır.
Metodun syntaxı:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);

şeklindedir.

Oluşturulan threadin kimliğini tutabilmek için
pthread_t *thread
şeklinde bir pointer tanımlarız.

Thread attributes (özelliklerini) ayarlayabilmek için kullanılan pointer ise,

const pthread_attr_t *attr

şeklindedir.

void*(*start_routine)(void *)

ise bir thread fonksiyonunun pointeridir.

void *arg

ise thread fonksiyonlarının parametresidir. Duruma göre ne gerekli ise gönderilebilir.

Threadlar ile ilgili bir C programı aşağıda görülmektedir.

Not: C dilinde threading yapabilmeniz için Unix sisteminizin olması gereklidir. Yani Windows bilgisayarlarda compile edemezsiniz. Virtual machine ile birlikte Linux yükleyerek deneyebilirsiniz.

Aşağıdaki thread örneğini herhangi bir isim ile kaydedin. (örneğin fp1.c)

gcc -pthread fp1.c -o pth1

komutunu çalıştırdıktan sonra,

./pht1 yazarak compile edebilirsiniz.

 

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void * print_message_function( void *ptr );
void * do_something_else( );
void * a_new_function();


int main()
{
pthread_t thread1, thread2,thread3,thread4;

char *message1 = "Thread 1 is running ";
char *message2 = "Thread 2";
int iret1, iret2,iret3;

void * (*f_ptr)();
f_ptr = do_something_else;




/* Create independent threads each of which will execute function */

iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);

printf("iret1: %d\n",iret1);
printf("thread1: %ld\n",thread1);


iret2 = pthread_create( &thread2, NULL, f_ptr/*do_something_else*/, NULL);

printf("iret2: %d\n",iret2);
printf("thread2: %ld\n",thread2);


iret3 = pthread_create( &thread3, NULL,a_new_function , NULL);
printf("iret3: %d\n",iret3);
printf("thread3: %ld\n",thread3);

pthread_join( thread1, NULL);
pthread_join( thread2, NULL); 
pthread_join( thread3, NULL);



return 0;
}

void * print_message_function( void *ptr )
{
int i; 

for(int i=0; i < 5; i++)
printf("%s \n", (char *)ptr);
}

void * do_something_else( )
{
int i; 

for(int i=0; i < 5; i++)
printf("%s \n", "thread2 is running");
}

void * a_new_function(){

int a;
int b;
int c;
a=5;b=7;
c=b+a;
//printf("This is third thread\n");
printf ("Thread3 says : the value of c =%d\n",c);

return 0;
}