반응형
정의
스레드(Thread) : 프로세스 내에서 실행되는 흐름의 단위를 말한다. 모든 프로그램은 하나 이상의 스레드를 가진다.
멀티 프로세스와 다르게 멀티 스레드는 스레드 간 프로세스 내 메모리를 공유할 수 있다는 장점이 있다.
=> 별도의 IPC가 필요없어서 더 빠르고, 더 간단하다.
단, 여러 스레드 중 어느 스레드가 실행되는 지 알 수 없어서, 스레드 간 동기화가 필요하다. 이를 위한 스레드가 뮤텍스 스레드(Mutex Thread)이다. 뮤텍스 스레드는 임계 영역을 설정하여, 해당 영역에서는 context 스위칭이 일어나지 않도록 방지하는 기능을 포함한다.
스레드의 종류
- User-Level Thread : 커널 영역 상위 레벨에서 지원되며, 일반 라이브러리로 스레드 생성 및 관리, 동일한 메모리 영역에서 스레드가 관리되므로 속도가 빠르나, 여러 개의 스레드 중 하나의 스레드가 시스템 콜에 종료되면 다른 스레드도 종료된다는 단점이 있다.
- Kernel-Level Thread : 운영체제가 지원하는 스레드 기능, 커널에 의해 스레드가 생성 및 관리된다. 시스템 호출 등으로 하나의 스레드가 중단되더라도, 나머지 스레드는 독립적으로 운영된다. 다만 User-Level Thread에 비해서 속도가 느리다.
일반 스레드 사용 예시
#include <stdio.h> /* printf() 함수를 위한 헤더 파일 */
#include <unistd.h>
#include <fcntl.h> /* O_CREAT, O_EXEC 매크로를 위한 헤더 파일 */
#include <pthread.h>
#include <semaphore.h> /* sem_open(), sem_destroy(), sem_wait() 등 함수를 위한 헤더 파일 */
sem_t *sem; /* 세마포어를 위한 전역 변수 */
static int cnt = 0; /* 세마포어에서 사용할 임계 구역 변수 */
void p() /* 세마포어의 P 연산 */
{
sem_post(sem);
}
void v() /* 세마포어의 V 연산 */
{
sem_wait(sem);
}
void *ptheadV(void *arg) /* V 연산을 수행하기 위한 함수를 작성한다. */
{
int i;
for(i = 0; i < 10; i++) {
if(cnt >= 7) usleep(100); /* 7 이상이면 100밀리초 동안 대기한다. */
cnt++;
printf("increase : %d\n", cnt) ;
fflush(NULL);
v();
}
return NULL;
}
void *ptheadP(void *arg) /* P 연산을 수행하기 위한 함수를 작성한다. */
{
int i;
for(i = 0; i < 10; i++) {
p(); /* 세마포어가 0이 되면 블록된다. */
cnt--;
printf("decrease : %d\n", cnt);
fflush(NULL);
usleep(100); /* 100밀리초 간 기다린다. */
}
return NULL;
}
int main(int argc, char **argv)
{
pthread_t ptV, ptP; /* 스레드를 위한 자료형 */
const char* name = "posix_sem";
unsigned int value = 7; /* 세마포어의 값 */
/* 세마포어 열기 */
sem = sem_open(name, O_CREAT, S_IRUSR | S_IWUSR, value);
pthread_create(&ptV, NULL, ptheadV, NULL); /* 스레드 생성 */
pthread_create(&ptP, NULL, ptheadP, NULL);
pthread_join(ptV, NULL); /* 스레드가 종료될 때까지 대기 */
pthread_join(ptP, NULL);
/* 다 쓴 세마포어 닫고 정리 */
sem_close(sem);
printf("sem_destroy() : %d\n", sem_destroy(sem));
/* 세마포어 삭제 */
sem_unlink(name);
return 0;
}
뮤텍스 스레드 사용 예시
#include <stdio.h>
#include <pthread.h>
int g_var = 1;
pthread_mutex_t mid;
void *inc_function(void *);
void *dec_function(void *);
int main(int argc, char **argv)
{
pthread_t ptInc, ptDec;
pthread_mutex_init(&mid, NULL); /* 뮤텍스 초기화 */
pthread_create(&ptInc, NULL, inc_function, NULL);
pthread_create(&ptDec, NULL, dec_function, NULL);
pthread_join(ptInc, NULL);
pthread_join(ptDec, NULL);
pthread_mutex_destroy(&mid); /* 뮤텍스 삭제 */
return 0;
}
void *inc_function(void *arg)
{
pthread_mutex_lock(&mid); /* 임계 구역 설정 */
printf("Inc : %d < Before\n", g_var);
g_var++;
printf("Inc : %d > After\n", g_var);
pthread_mutex_unlock(&mid); /* 임계 구역 해제 */
return NULL;
}
void *dec_function(void *arg)
{
pthread_mutex_lock(&mid); /* 임계 구역 설정 */
printf("Dec : %d < Before\n", g_var);
g_var--;
printf("Dec : %d > After\n", g_var);
pthread_mutex_unlock(&mid); /* 임계 구역 해제 */
return NULL;
}
코드 출처 : https://github.com/valentis/LinuxProgrammingWithRaspberryPi/tree/master/Chapter5
LinuxProgrammingWithRaspberryPi/Chapter5 at master · valentis/LinuxProgrammingWithRaspberryPi
Linux Programming With Raspberry Pi. Contribute to valentis/LinuxProgrammingWithRaspberryPi development by creating an account on GitHub.
github.com
thread.c, thread_mutex.c
반응형
'컴퓨터 과학 > 리눅스 프로그래밍' 카테고리의 다른 글
[이론]리눅스 드라이버 원리 (1) | 2025.05.19 |
---|---|
[이론]리눅스 프로그래밍 - 네트워크(TCP/IP, UDP) (2) | 2025.05.09 |
[이론] 세마포어(Semaphore) (0) | 2025.05.08 |
[이론]리눅스 프로그래밍 - 프로세스와 쓰레드 (1) | 2025.05.08 |
[이론] 리눅스 프로그래밍 - 입출력 함수 (0) | 2025.05.06 |