네트워크 프로그래밍 - 다중 접속 서버 구현을 위한 이론 1 ( feat. 쓰레드 )
안녕하세요! WH입니다.
이번 글은 다중 접속 서버 구현 중 쓰레드를 활용한 내용인데요.
그 중에서도 쓰레드에 대해 필요한 이론 부분들을 짚고 가겠습니다.
멀티 프로세스 기반 서버의 단점이 새로운 클라이언트가 연결될 떄마다 프로세스를 생성하기 떄문에 비용이 크고 비효율적이며, context switching 때문에 성능이 저하 된다고 말했었죠?? 그래서 쓰레드를 가자고 이 문제의 일부를 해결해 보고자 합니다.
Thread
저번 글에서 간단하게 설명드렸지만, Thread( 쓰레드 )는 프로세스를 구성하는 실행 흐름으로 단위가 작다고 말씀드렸죠? 프로세스는 독립적인 메모리 공간을 사용하기 때문에, 메모리 모든 영역의 복사가 일어난다고 했었고, 쓰레드의 경우 스택 영역만 복사가 일어나고 나머지는 공유를 한다고 했었습니다.
쓰레드와 프로세스의 관계를 보면 쓰레드는 프로세스의 일부분이며, 한 프로세스 내 여러 쓰레드는 프로세스의 메모리 공간을 공유할 수 있답니다. 물론 쓰레드 자체는 독립적인 실행 흐름을 보장하기 위해 메모리를 할당 받지요. 그니까 쉽게 그냥 스택은 복사한다라고 생각하셔도 무방합니다. 여튼 결론은 쓰레드는 프로세스보다 가볍다 입니다.
Thread 생성
int pthread_create(pthread_t* restrict thread, const pthread_arrt_t * attr,
void *(*start_routine)(void*), void*restrict arg);
반환 값 : 성공 시 0, 실패 시 다른 값
thread : 생성할 쓰레드의 ID를 저장할 주소값 전달
attr : 쓰레드에 부여할 속성 정보
start_routine : 쓰레드의 메인 함수가 되는 함수 주소
arg : 쓰레드에 등록된 함수가 호출될 떄 전달할 인자
뭐 이런 인자들을 가지고 쓰레드를 생성하게 됩니다. 쓰레드 생성시에는 등록된 함수가 생성한 쓰레드에서 실행됩니다.
Thread Join
join이 뭐하는 거냐면, 쉽게 생성된 쓰레드가 종료되어 반환값이 전달되기 전까지 블로킹 상태에 있도록하는 함수에요. 그니까 이런 경우가 있어요. 쓰레드를 생성한 상위 쓰레드가 있을 거에요. 근데, 그 상위 쓰레드가 종료되면 해당 객체가 소멸하고 그럼 그 하위 쓰레드도 소멸될 수 있단 말이죠? 그니까 그 종료를 늦춰주는 함수가 join이에요. 쉽죠?
Thread detach
이번에는 같은 문제를 다른 관점에서 바라봅시다. 아까는 상위 쓰레드와 하위 쓰레드가 독립적이지 못해서 발생한 문제였어요. 그래서 어떻게 했죠? join을 통해 반환값이 올때 까지 상위 쓰레드의 종료를 늦췄던 거죠. 근데 이번에는 그게 아니라, 아예 분리를 해버리는 거에요. 그럼 상위 쓰레드가 소멸되든 말든, 하위 쓰레드는 신경을 쓰지 않아도 되는거죠.
임계 영역
임계 영역이란 공유 자원을 사용하는 둘 이상의 쓰레드가 동시에 실행되면 문제를 일으키는 문장이 있는 영역이 하나 이상인 영역을 말합니다. 동시에 실행되면 문제가 일어난다는 게 무슨말이냐면, 자원에 어떻게 접근하느냐에 따라 결과가 달라지는 것을 말해요. 그니까 더 쉽게 쓰레드는 분리되어 있는데, 동시에 호출했을 때 그 값들이 서로 다른 경우 문제가 있다고 말하는 거죠.
임계 영역 문제 해결방법
프로세스 동기화를 통해 해결할 수 있는데요, 동기화가 사용되는 대표적인 상황이 있어요.
1. 동일한 메모리 영역으로 동시 접근이 발생하는 상황
2. 동일한 메모리 영역에 접근한느 쓰레드의 실행 순서를 지정해야 하는 상황
그니까 쉽게 이런 상황에 동기화를 해주면 공유 자원으로 임계 영역이 생기는 문제를 막을 수 있다는 말이지요. 대표적인 동기화 기법으로는 Mutex ( 뮤텍스 )가 있어요. 쓰레드의 동시 접근을 허용하지 않고, 먼저 임계영역을 접근하는 쓰레드가 자물쇠를 잠그고 일을 한 다음 임계 영역을 나가며 자물쇠를 푸는 방식인 것이지요. 세마 포어라는 기법도 있지만, 간단하게만 말하면 임계 영역을 접근하는 쓰레드 수를 제어하는 기법이랄까요? 여튼 이정도가 되겠네요.
다음 글에서 쓰레드를 활용하여 구현한 서버 코드를 만나도록 하자구요.
이상 WH였습니다. 감사합니다.