본문 바로가기

공부/tcp/ip 프로그래밍

18장 멀티쓰레드 기반의 서버구현

반응형

 멀티 쓰레드.pptx

 

하나의 cpu에서 함수를 동시에 실행한다는 것은 context switch이 자주 빠르게 일어난다는 의미

예) 쓰레드1 처리 도중-> 쓰레드1의 내용 저장 -> 쓰레드2를 처리 -> 쓰레드2를 처리를 완료하고 쓰레드1의 내용을 복원 -> 쓰레드1 처리완료

 

쓰레드 구조 

쓰레드는 데이터 영역, 힙 영역, 코드 영역은 공유 하지만 스택영역은 각자 독립적으로 사용

 

코드영역: 프로그램의 실제 코드가 저장되어 있는 영역

스택영역 : 로컬변수, 함수에 호출에 관련된 정보, 임시데이터가 저장되는 영역

영역 : 동적 메모리 할당에 사용되는 영역

데이터영역 : 전역변수등의 데이터가 저장되는 영역

 

-D_REENTRANT(= 헤더파일 선언 이전에 매크로 _REENTRANT를 정의)

임계영역에서 동시호출시 문제가 발생할 수 있는 함수를 문제가 발생하지 않는 함수로 바꿔주는 기능

 

-lpthread

컴파일시 쓰레드 라이브러리의 링크를 별도로 지시

 

쓰레드의 생성

#include <pthread.h>

 

int pthread_create(pthread_t* restrict thread, const pthread_attr_t* restrict attr, void* (*strat_routine)(void*), void* restrict arg);

성공시 0, 실패시 0 이외의 값 반환

 

thread : 생성할 쓰레드의 ID 저장을 위한 변수의 주소 값 전달, 참고로 쓰레드는 프로세스와 마찬가지로 쓰레드의 구분을 위한 ID가 부여

attr : 쓰레드에 부여할 특성 정보의 전달을 위한 매개변수, NULL 전달 시 기본적인 특성의 쓰레드가 생성됨

start_routine : 쓰레드의 main함수 역할을 하는, 별도 실행흐름의 시작이 되는 함수의 주소 값(함수 포인터)전달

arg : 세 번째 인자를 통해 등록된 함수가 호출될 때 전달할 인자의 정보를 담고 있는 변수의 주소 값 전달

 

쓰레드의 종료하기를 대기하고 종료시 반환 값을 받는 함수

쓰레드가 종료되었다고 해서 쓰레드에 할당된 자원이 삭제되는 것 아님 이 함수를 호출해야 삭제됨

#include <pthread.h>

 

int pthread_join(pthread_t thread, void** status);

성공시 0, 실패시 0 이외의 값 반환

 

thread : 이 매개변수에 전달되는 ID의 쓰레드가 종료될 때까지 함수는 반환하지 않는다

status : 쓰레드의 main함수가 반환하는 값이 저장될 포인터 변수의 주소 값을 전달

 

 

쓰레드의 문제점과 임계영역(critical section)

임계영역 : 함수 내에 둘 이상의 쓰레드가 동시에 실행하면 문제를 일으키는 하나 이상의 문장으로 묶여있는 코드 블록

 

쓰레드의 문제점

<1>

 

 

<2>

 

 

<3>

 

 

<4>

 

 

<5>

 

 

<6>

 

 

<7>

 

 

<8>

결과 값을 6로 예상했지만 실제 결과값은 5가 나옴

 

 

동기화가 필요한 대표적인 상황

1. 동일한 메모리 영역으로의 동시접근이 발생하는 상황

 

 

2. 동일한 메모리 영역에 접근하는 쓰레드의 실행순서를 지정해야 하는 상황

 

동기화 기법

1. 뮤텍스(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 : 뮤텍스 생성시에는 뮤텍스의 참조 값 저장을 위한 변수의 주소 값 전달, 그리고 뮤텍스 소멸 시에는 소멸하고자 하는 뮤텍스의 참조 값을 저장하고 있는 변수의 주소 값 전달

attr : 생성하는 뮤텍스의 특성정보를 담고 있는 변수의 주소 값 전달, 별도의 특성을 지정하지 않을 경우에는 NULL 전달

 

뮤텍스에 열쇠를 가지고 진입하는 함수(임계영역의 시작)

#include <pthread.h>

 

int pthread_mutex_lock(pthread_mutex_t* mutex);

성공시 0, 실패시 0 이외의 값 반환

 

mutex : 뮤텍스의 참조 값 저장을 위한 변수의 주소 값 전달

 

뮤텍스에서 빠져나와 열쇠를 반납하는 함수(임계영역의 끝)

#include <pthread.h>

 

int pthread_mutex_unlock(pthread_mutex_t* mutex);

성공시 0, 실패시 0이외의 값 반환

 

mutex : 뮤텍스의 참조 값 저장을 위한 변수의 주소 값 전달

 

다른 쓰레드가 pthread_mutex_lock함수로 뮤텍스를 사용하고 있으면 pthread_mutex_lock함수로 진입불가

다른 쓰레드가 pthread_mutex_unlock함수로 뮤텍스를 빠져 나갈 때까지 블로킹 상태로 기다림

다른 쓰레드가 빠져 나오면 그때 진입

 

2. 세마포어(semaphore)기반 동기화

여러 개의 열쇠로 여러 사람(프로세스 or 쓰레드)가 임계구역을 이용하도록 함

세마포어 생성 함수 및 소멸 함수

#include <semaphorer.h>

int sem_init(sem_t* sem, int pshared, unsigned int value);

int sem_destroy(sem_t* sem);

성공시 0, 실패시 0 이외의 값 반환

 

sem : 세모포어 생성시에는 세마포어의 참조 값 저장을 위한 변수의 주소 값 전달, 그리고 세마포어 소멸 시에는 소멸하고자 하는 세마포어의 참조 값을 저장하고 있는 변수의 주소 값 전달

pshared : 0 이외의 값 전달 시, 둘 이상의 프로세스에 의해 접근 가능한 세마포어 생성, 0  전달시 하나의 프로세스에서만 접근 가능한 세마포어 생성

value : 생성되는 세마포어의 초기 값 지정

 

세마포어에 열쇠를 가지고 진입하는 함수(임계영역의 시작)

#include <semaphore.h>

 

int sem_wait(sem_t* sem);

성공시 0, 실패시 0 이외의 값 반환

 

sem : 세마포어의 참조 값을 저장하고 있는 변수의 주소 값 전달, sem_wait에 전달되면 세마포어의 값은 하나 감소

 

세마포어에서 빠져나와 열쇠를 반납하는 함수(임계영역의 끝)

#include <semaphore.h>

 

int sem_post(sem_t* sem);

성공시 0, 실패시 0이외의 값 반환

 

sem : 세마포어의 참조 값을 저장하고 있는 변수의 주소 값 전달, sem_post에 전달되면 세마포어의 값은 하나 증가

 

다른 쓰레드들이 sem_wait함수를 사용하여 세마포어 값이 0이 되면 sem_wait함수로 진입불가

다른 쓰레드들이 sem_post함수를 사용하여 세마포어 값이 1이상이 될 때까지 블로킹상태로 기다림

세마포어 값이 1이상이 되면 그때에 진입

 

쓰레드가 끝나기를 기다리는 것이 아니라

쓰레드에게 종료의 권한을 주어 쓰레드가 끝나면 쓰레드에서 사용되는 자원을 스스로 삭제하게 하는 함수

#include <pthread.h>

 

int pthread_detach(pthread_t thread);

성공시 0, 실패시 0 이외의 값 반환

 

thread : 종료와 동시에 소멸시킬 쓰레드의 ID정보 전달

반응형