프로그래밍에서 스레드란?
프로세스는 1개의 메인 스레드로 구성되어 코드가 실행되는 주체입니다.
하나의 프로세스에서 독립적으로 2개 이상의 코드를 병렬 처리하기 위해서 우리는 스레드를 사용합니다.
즉, 스레드는 독립적인 실행을 수행하며 하나의 프로세스 안에서 여러 개의 스레드를 동시에 실행할 수 있습니다.
우리는 이러한 처리를 병렬처리라고 합니다.
개별 스레드는 자신만의 스텍 메모리 영역을 가지고 관리하며 1개의 부모 프로세스 내에서 자원을 서로 공유할 수 있습니다.
여기서 자원이라 함은 곧 변수를 의미하기도 합니다.
한 개의 일만 처리하는게 아닌 동시에 여러 개의 일을 처리할 수 있으므로 우리 프로그램의 작업 성능을 향상합니다.
C언어에서 pthread란?
C 언어에서 pthread는 POSIX 스레드를 구현한 모듈입니다.
POSIX는 이식성이 높습니다. 우리가 사용하는 운영체제의 인터페이스 계층의 표준이 됩니다.
여러 운영체제들에서 같은 API를 사용하여 스레드를 생성, 소멸, 관리할 수 있도록 도와줍니다.
이러한 pthread 라이브러리는 C 언어에서 스레드를 사용하기 위한 함수를 제공합니다.
C언어에서 pthread 생성 후 독립 실행 예제
pthread를 사용하여 스레드를 생성하고 독립적으로 실행하는 예제를 살펴보겠습니다.
아래는 C 언어에서 pthread를 활용한 스레드 생성 예제입니다.
참고로 pthread 라이브러리를 프로젝트에 추가해 줘야 사용할 수 있습니다.
#include <stdio.h>
#include <pthread.h>
void* thread_entry(void* dummy) {
int n = *(int*)dummy;
printf("전달 받은 값 %d\n", n);
return NULL;
}
int main() {
pthread_t thread;
int num = 1;
pthread_create(&thread, NULL, thread_entry, (void*)&num);
pthread_join(thread, NULL);
return 0;
}
위의 예제는 pthread_create API를 사용하여 스레드를 생성하고, pthread_join 함수를 사용하여 스레드가 끝날 때까지 대기하는 예제입니다.
생성된 스레드는 thread_func 함수를 실행하고, pthread_join 함수가 호출될 때까지 메인 스레드와 독립적으로 작업을 수행합니다.
스레드의 블록킹(Blocking)이란?
스레드의 Blocking은 스레드가 어떤 이벤트를 기다리는 동안 대기 상태에 있음을 의미합니다.
Blocking은 스레드의 실행을 일시 중지시키는 특성을 갖고 있으며, 주로 입출력 작업이나 잠금 등의 동기화 작업에서 발생합니다.
스레드가 Blocking 되면 다른 스레드가 실행될 기회를 얻게 되어 동시성을 향상하는 효과가 있습니다.
하지만 예기치 못한 블록킹 상태는 프로그램이 일시중지되는 상태가 되어 큰 오류를 발생시킬 수 있습니다.
따라서 우리는 이런 스레드의 상태와 상관없이 메인 스레드 즉, 프로세스가 계속 진행되려면 생성한 스레드를 Non Blocking 상태로 만들어줘야 합니다.
C언어에서 Non Blocking 스레드 생성 예제
C 언어에서 Non Blocking 스레드를 생성하는 예제를 살펴보겠습니다
아래는 pthread의 pthread_detach 함수를 사용하여 스레드를 Non Blocking으로 설정하는 예제입니다.
#include <stdio.h>
#include <pthread.h>
void* thread_entry(void* dummy) {
int n = *(int*)dummy;
printf("전달 받은 값 %d\n", n);
return NULL;
}
int main() {
pthread_t thread;
int num = 1;
pthread_create(&thread, NULL, thread_entry, (void*)&num);
pthread_detach(thread);
return 0;
}
위의 예제에서 pthread_detach 함수를 사용하여 생성된 스레드를 Non Blocking으로 설정합니다.
이렇게 설정된 스레드는 자동으로 종료되며, 메인 스레드는 pthread_join을 호출하지 않아도 됩니다.
Join으로 스레드 종료 대기 예제
스레드의 종료를 대기하기 위해 pthread_join 함수를 사용하는 예제를 살펴보겠습니다.
아래는 생성된 스레드의 작업이 완료될 때까지 메인 스레드가 대기하는 예제입니다.
#include <stdio.h>
#include <pthread.h>
void* thread_entry(void* dummy) {
int n = *(int*)dummy;
printf("전달 받은 값 %d\n", n);
return NULL;
}
int main() {
pthread_t thread;
int num = 1;
pthread_create(&thread, NULL, thread_entry, (void*)&num);
pthread_join(thread, NULL);
return 0;
}
위의 예제에서 pthread_join 함수는 생성된 스레드가 작업을 완료할 때까지 메인 스레드를 대기시킵니다.
이런 방법을 통해 뒤의 일 처리를 반드시 사전 스레드가 종료된 걸 확인하고 처리할 수 있도록 할 수 있습니다.
프로그램의 안정성이 높아집니다.
오늘은 C 언어에서 pthread를 활용하여 스레드를 생성하고 제어하는 방법에 대해 알아보았습니다.
스레드를 사용하면 병렬 처리와 동시성을 효과적으로 구현할 수 있으며, 프로그램의 성능을 향상할 수 있습니다.