Linux/Thread

Linux에서의 Thread 와 Mutex. (lpthread)

Ohjeonghak 2013. 7. 19. 21:36
반응형

Linux에서의 Thread (lpthread).


일단 Thread에 대해 설명들어가기 전에 프로세스에 대해 설명 하도록 하겠다.

사람들이 흔히 알고 있는 프로세서와 프로세스 많이들 착각하고 둘 다 같은것 아니야~? 라는 잘못된 생각을 가진 사람들이 있다. 하지만 전혀 다르다. 프로세서는 말 그대로 처리자 이다. 즉, 컴퓨터의 CPU라고 할 수 있다.

그리고 프로세스는 프로세서에서 처리되는 프로그램이라 할 수 있다. 프로세스 내부에는 n개의 Thread가 존재 할 수 있으며, 여러개의 프로세스가 특정 자원들을 사용하며 함께 작동되어 돌아갈 때 프로세스 간의 통신을 시그널로 할 수 있다.

물론 시그널을 이용해서 프로세스 내부의 Thread를 동기화를 위해 사용 하는 방법 도 있으며, 임계영역(Critical Section)의 해결을 위해 사용 되기도 한다.





Thread 함수


-Thread 를 사용하기 위해 필요한 헤더.

#include<pthread.h>


-Thread 사용에 관련 된 함수.

 

*Thread 생성 함수

프로세스의 main함수에서 Thread를 생성 하기 위해 사용되는 함수이다. 기본형은 다음과 같다.

int pthread_create(pthread_t *thread,          //Thread 식별자
                   const pthread_attr_t *attr,    //Thread의 특성을 설정
                   void *(*start_routine)(void*), //Thread 의 main 함수
                   void *arg);                    //Thread 의 main 함수에 전달할 인자 값


*Thread 대기 함수.

프로세스의 main함수에서 생성한 Thread 들이 종료 될때 까지 프로세스의 종료를 대기 하는 함수이며

기본형은 다음과 같다.

int phread_join(pthread_t th,           //기다릴 Thread 식별자
                  void **thread_return);   //Thread 의 리턴 값이다. NULL이 
                                           //아니면 포인터로 값을 받아 올 수 있다.


*Thread 종료 함수

void pthread_exit(void *retval);


임계영역(Critical Section) 동기화를 위한 Mutex



-Mutex 를 사용하기 위해 필요한 헤더.

#include<stdlib.h>
#include<unistd.h>


-Mutex 객체 선언과 초기화

//mutex 객체는 상수 PTHREAD_COND_INITIALIZER 을
// 이용해서도 초기화 할 수 있다. 
pthread_mutex_t mutex = PTHREAD_COND_INITIALIZER;


-Mutex 조건변수 선언과 초기화

//조건변수 cond는 상수 PTHREAD_COND_INITIALIZER 을
// 이용해서도 초기화 할 수 있다. 
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;



-Mutex 사용에 관련 된 함수


*Mutex lock 함수

공유하고 있는 자원이 있어서 동기화를 할 때 critical section에 들어가기 위해서 mutex lock을 요청 한다. 만약 다른 Thread에서 mutex lock을 얻어서 사용하고 있다면 다른 Thread에서 mutex lock을 해제 할때까지 블럭된다.

함수의 기본형은 다음과 같다.

int pthread_mutex_lock(pthread_mutex_t *mutex);
만약 다른 Thread에서 mutex lock을 사용하지 않는다면 즉시 mutex lock을 얻게 되고 critical section에 진입하게 된다.


*Mutex unlock 함수

critical section에서의 모든 작업을 마치고 mutex lock을 돌려주기 위해 사용한다.

기본형은 다음과 같다.

int pthread_mutex_unlock(pthread_mutex_t *mutex);


*cond_signal 함수

조건변수 cond에 signal을 보낸다. signal을 보낼 경우 cond에서 기다리는 Thread가 있다면  Thread를 깨우게(블럭이 풀림) 된다. 만약 조건변수 cond를 기다리는 Thread가 없다면 아무런 일도 일어나지 않게 되고, 여러개의 Thread가 기다리고 있다면 그 중의 하나의 쓰레드에게만 전달 된다. 기본형은 다음과 같다.

int pthread_cond_signal(pthread_cond_t *cond);


*cond_wait 함수

조건변수 cond를 통해서 신호가 전달될때까지 블럭 된다. 만약 신호가 전달되지 않는다면 영원히 블럭 될 수 있다.

함수의 기본형은 다음과 같다.

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

실습.

-Thread와 Mutex를 이용한 예제

 #include<stdio.h>
 #include<stdlib.h>
 #include<pthread.h>
 #include<unistd.h>
 
 int a=0, b=0, input=0, count=0;
 
 pthread_mutex_t thread_MutexA = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t thread_MutexB = PTHREAD_MUTEX_INITIALIZER;
 
pthread_cond_t Cond_A = PTHREAD_COND_INITIALIZER;
 pthread_cond_t Cond_B = PTHREAD_COND_INITIALIZER;
 
void *Thread_A(void *arg)
 {
    while(1)
   {
      pthread_mutex_lock(&thread_MutexA);
       if(input<2)
       pthread_cond_wait(&Cond_A, &thread_MutexA);
      if(input==count)
       {
         pthread_cond_signal(&Cond_B);
          break;
       }
 
       if(count==0)
       {
          b++;
          count++;
          printf("%d\n", a);
       }
       else if(count%2==0)
       {
         a+=b;
          count++;
          printf("%d\n", a);
       }
 
       pthread_cond_signal(&Cond_B);
       pthread_cond_wait(&Cond_A, &thread_MutexA);
 
       pthread_mutex_unlock(&thread_MutexA);
    }
 }
 
 void *Thread_B(void *arg)
 {
    while(1)
    {
       pthread_mutex_lock(&thread_MutexB);
       if(input<2)
       pthread_cond_wait(&Cond_B, &thread_MutexB);
 
       if(input==count)
       {
         pthread_cond_signal(&Cond_A);
          break;
       }
 
       if(count==1)
       {
          count++;
          printf("%d\n", b);
       }
       else if(count%2!=0)
       {
          b+=a;
          count++;
          printf("%d\n", b);
       }
 
       pthread_cond_signal(&Cond_A);
       pthread_cond_wait(&Cond_B, &thread_MutexB);
 
       pthread_mutex_unlock(&thread_MutexB);
    }
 }
 
 int main()
 {
    pthread_t p_thread[2];
 
    int thr_a, thr_b;
    int status;
 
    thr_a = pthread_create(&p_thread[0], NULL, Thread_A, (void*)NULL);
    if(thr_a < 0)
    {
       perror("thr_a create error : ");
       exit(1);
    }
 
    thr_b = pthread_create(&p_thread[1], NULL, Thread_B, (void*)NULL);
    if(thr_b < 0)
    {
       perror("thr_b create error : ");
       exit(1);
    }
 
    while(1)
    {
       printf("2개 이상의 개수 입력 : ");
       scanf("%d", &input);
       if(input>2)
       {
          pthread_cond_signal(&Cond_A);
          break;
       }
    }
 
    pthread_join(p_thread[0], (void **)&status);
    pthread_join(p_thread[1], (void **)&status);
 
    printf("complete ! \n");
 
    return 0;
}



thread 를 사용한 소스 파일은 컴파일 할때 -lpthread 라는 옵션을 줘야 한다.

(예 :  gcc -o test  test.c -lpthread )

반응형