임베디드

[Thread] POSIX 멀티스레드 예시 작성하기

히똔 2022. 4. 19. 16:20
728x90
반응형

멀티스레드를 구현하기 위해서 POSIX API를 이용해야한다.

 

POSIX

임베디드 어플리케이션 개발자는 제품마다 사용되는 OS가 다 다르기 때문에 각 OS마다 API 각각 알아야했다.
이런 불편함을 줄여주는 POSIX API는 OS마다 제공되는 API를 하나로 통일하였다.

IEEE에서 제정한 API 표준 규격으로, POSIX API만 배워두면 여러 임베디드 OS에서도 편리하게 어플리케이션 개발이 가능하다.

 

멀티스레드가 필요한 이유

특정 함수를 동시에 동작시키고 싶을 때 사용한다.

이전 글에서 이용한 예시를 이어서 스레드의 필요성에 대해 설명해보겠다.

멀티스레드 실패 예시

위 코드는 abc 함수가 끝나지 않기 때문에 bts 함수가 시작도 못한다.
하지만 개발자의 의도는 abc 함수와 bts 함수가 동시에 동작하는 것이다.

그렇게 하기 위해서는 멀티스레드를 이용해야한다.

 

멀티스레드 코드 작성하기

일단 POSIX Thread 라이브러리인 pthread library를 인클루드한다.

#include <pthread.h>

 

Thread 함수 작성하기

thread 함수의 기본 interface는 void * 를 리턴 받는 형태이다.

그래서 위 abc 함수와 bts 함수를 이와 같은 형태로 작성해본다면

void *abc(){
    while(1){
        printf("ABC\n");
        sleep(1);
    }
    return 0;
}

void *bts(){
    while(1){
        printf("BTS\n");
        sleep(1);
    }
    return 0;
}

이렇게 완성할 수 있다.

 

Thread 함수의 생성과 삭제

이렇게 작성한 thread 함수는 create를 통해 함수를 생성하고 join을 통해 함수를 제거해야 한다.

 

생성 코드 : pthread_create

pthread_create(thread_id,스레드 속성, 함수, 파라미터);
Arg1 thread id 저장될 변수의 주소
Arg2 스레드 속성 (설정), 기본적으로 NULL이다. 우선순위를 담당함
Arg3 실행할 함수의 이름
Arg4 함수에 인자 값을 전달해주고 싶을 때 사용

 

위 정보를 가지고 abc 함수와 bts 함수를 생성해보는 코드를 작성해보자.

pthread_t t1, t2;

pthread_create(&t1, NULL, abc, NULL);
pthread_create(&t2, NULL, bts, NULL);

먼저 pthread_t 자료형으로 thread id 를 담을 변수 두개를 선언하고, create 첫번째 파라미터에 해당 변수를 넣어준다.
우리는 우선순위를 고려하지 않기 때문에 두번째 파라미터에 NULL로 설정해주고
각 함수를 세번째 파라미터에 넣어서 두 스레드가 생성되도록 한다.
abc 와 bts 함수는 인자가 필요 없기 때문에 마지막 파라미터에 NULL을 넣어준다.

 

삭제 코드 : pthread_join

pthread_join(thread_id, thread 리턴값);

join 코드를 만나면 해당 스레드의 종료를 계속 기다린다. 종료되지 않으면 다음 코드가 실행되지 않는다.

만약 pthread_join 처리를 해주지 않으면 thread가 종료되어도 메모리해제가 되지 않기 때문에 반드시 써주자.

 

생성한 abc와 bts 함수를 join으로 삭제해보자.

pthread_join(t1,NULL);
pthread_join(t2,NULL);

 

멀티스레드 예시 전체 코드

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

void *abc(){
    while(1){
        printf("ABC\n");
        sleep(1);
    }
    return 0;
}

void *bts(){
    while(1){
        printf("BTS\n");
        sleep(1);
    }
    return 0;
}

int main(){
    pthread_t t1, t2;

    pthread_create(&t1, NULL, abc, NULL);
    pthread_create(&t2, NULL, bts, NULL);

    pthread_join(t1,NULL);
    pthread_join(t2,NULL);

    return 0;
}

 

멀티스레드 코드 빌드하기

빌드 시 pthread library를 link 해주기 위해 옵션을 추가해주어야한다.

gcc thread.c -o thread -lpthread && ./thread

 

실행결과

 

실행해보면 ABC와 BTS가 동시에 실행되는 것을 볼 수 있다.
그런데 또 주목해볼만 한 것은 ABC와 BTS가 순서대로 출력되지 않는다는 것이다.
언제는 ABC먼저, 어떤때는 BTS 먼저 실행한다.

그 이유는 순차적으로 CPU를 할당해주지 않기 때문이다.
우선순위를 정하면 어느정도 조절할 수 있지만 여기서는 NULL로 설정해주었다.

728x90
반응형