스레드의 사용 이유
프로세스
- 프로세스 생성에 많은 리소스 사용
- 프로세스의 컨텍스트 스위칭으로 성능 저하
- 프로세스간 메모리가 독립적으로 운영되어, 별도의 메모리 공간으로 IPC 기법의 적용이 필요
- 프로세스는 독립된 스택 / 힙 / 데이터 영역을 가진다.
스레드
- 가벼워 컨텍스트 스위칭이 빠르다.
- 스레드간 메모리 공유가 가능하다.
- 스레드는 데이터와 힙 영역을 공유한다.
- 전역 변수는 어느 스레드에서든 사용 가능하다.
pthread.h
- gcc로 컴파일시 -lpthread 를 붙혀 pthread를 link 하는 과정이 필요하다.
스레드 생성
#include <pthread.h>
int pthread_create(pthread_t* restricted thread, cons pthread_attr_t* restrict attr, void*(*start_routine), void* restrict arg);
성공시 0, 실패시 0 이외 값 반환
- thread : 생성할 쓰레드의 ID 저장 위한 변수 주소 값 ( pthread_t )
- attr : 쓰레드에 부여할 특성 정보, 본 강의에선 NULL 을 넣으면 된다.
- start_routine : 쓰레드의 main 함수역할을 할 함수
- arg : 등록되 함수가 호출될때 전달할 인자의 정보
사용 예시
스레드의 종료를 대기
#include <pthread.h>
int pthread_join(pthread_t thread, void** status);
성공시 0, 실패시 이외의 값 반환
- thread : 종료를 기다릴 스레드
- status : 스레드의 함수가 반환하는 값.
- 해당 특정 스레드가 값을 리턴 할 때 까지 blocking 된다.
사용 예시
임계 영역
- 둘 이상의 스레드가 동시 호출시 문제를 일으키는 함수 : 불안전한 함수 / Thread-unsafe function
- 둘 이상의 스레드가 동시에 호출해도 괜찮은 함수 : 안전한 함수 / Thread-safe function
worker thread model
- 쓰레드에 일을 시키고, 그 결과를 취합하는 모델
사용 예시
스레드 동시접근 문제
스레드 동기화
- 동일한 메모리에 접근하는 스레드의 실행 순서를 지정한다.
Mutex 기반
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr);
int pthread_mutex_destroy(pthread_mutex_t* mutex);
성공시 0, 실패시 0 이외의 값 반환
- mutex : pthread_mutex_t - 자물쇠와 같은 역할
- attr : 설정 정보, 여기선 NULL 집어 넣으면 된다.
사용 예시
Semaphore 기반
#include <pthread.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t* sem);
성공시 0, 실패시 0 이외의 값 반환
- sem : sem_t, 참조 값 저장
- pshared : 0 전달시 하나의 프로세스만 접근 가능, 이외는 여러 프로세스 접근 가능. 본 강의는 0 사용
- value : 생성되는 세마포어의 초기 값
사용 방법
- sem_wait(&sem) 의 동작
- sem 의 값이 0이면 blocking 된다.
- sem 의 값이 0보다 크면 sem_t의 값을 1 내리고 아래 코드로 진행한다.
- sem_post(&sem) 의 동작
스레드 소멸
#include <pthread.h>
int pthread_detach(pthread_t th);
성공시 0, 실패시 0 이외의 값을 반환
- 쓰레드 식별자th를 가지는 쓰레드를 메인쓰레드에서 분리 시킨다.
이것은 th를 가지는 쓰레드가 종료되는 즉시 쓰레드의 모든 자원을 되돌려(free)줄 것을 보증한다.
멀티 스레드 서버 구현