1. 멀티 프로세스 통신의 한계
이전에는 멀티 프로세스를 활용하여 멀티 클라이언트와 TCP통신을 해보았다. 간략하게 그 방식을 정리해보자면 서버의 부모프로세스가 listening socket에서 각 클라이언트로 부터 연결 요청을 받으면 listening queue에 쌓고, 하나씩 연결 한 후에 folk, dup을 통해 자식 프로세스에게 연결을 전달(복사)하여 자식프로세스가 클라이언트와 통신을 하게 하는 방식으로, 통신 자체는 자식프로세스에게 맡기고 부모프로세스는 연결 및 자식 프로세스 생성만 맡는 형태였다.
하지만 이 방식에는 문제가 있었으니, 자식 프로세스를 생성하는 과정에서 너무나도 불필요한 메모리들이 복사가 된다는 점이었다. 이 오버해드를 해결해주는 방식이 바로 쓰레드이다.
쓰레드의 경우에는 stack영역을 제외한 모든 영역(Code, Data, Heap)을 공유섹션으로 관리하여, 자식프로세스를 활용할 경우보다 메모리가 훨씬 더 절약되는 방식이다.
멀티 프로세스보다 까다롭다는 단점이 있지만, 쓰레드간에 메모리를 "공유"하여 절약한다는 장점 때문에 자주 사용된다고 한다.
우선 쓰레드(Thread)란 무엇일까?
2. 쓰레드의 정의
쓰레드란? : 프로세스에서 실행되는 흐름의 단위로이다.
그렇다면 어떻게 이 쓰레드를 생성하고 관리할까?
쓰레드 관련 함수들은 pthread.h에 정의되어 있고 다음과 같은 함수들이 존재한다.
a. 쓰레드의 생성 : pthread_create
인자를 살펴보자면 thread는 쓰레드의 ID가 저장될 구조체이고, attr은 쓰레드의 속성을 정의하는 구조체이고, start_routine은 thread와 함께 호출될 함수의 포인터이고, arg는 그 함수에게 전해지는 매개변수들이다.
attr과 arg은 NULL로 설정될 수 있다.
리턴으로는 쓰레드 생성에 대한 결과를 출력한다. 예시로 잘못된 권한 혹은 attr 세팅 등이 존재한다.
b. 쓰레드의 종료 대기 : pthread_join
이렇게 생성된 쓰레드의 경우에는 메인 쓰레드와 독립된 흐름을 갖는 쓰레드로 만약 메인 쓰레드가 먼저 실행을 다 마친 경우에는 모든 쓰레드가 실행 도중에 종료되게 된다. 혹은 의도적으로 쓰레드의 종료를 기다리도록 구현해야할 수 있다. 이러한 이유로 쓰레드의 종료를 기다리게 해줄 명령이 필요한 것이다.
pthread_join의 실행 시 인자로 전달된 쓰레드가 종료되기를 기다리고, 종료 시그널이 도착하면 다시 실행하게 된다.
이는 pthread_join를 이용하면 사용할 수 있다.
인자를 한번 확인해보자. thread는 쓰레드 생성, pthread_create에서 전달받은 thread id이고, retval은 그 thread가 종료하면서 반환하는 값에 접근할 수 있는 더블 포인터이다.
리턴값으로는 성공한다면 0을, 실패한다면 오류에 해당하는 값을 리턴한다.
c. 종료 시 스레드 자원 반납 예약 : pthread_detach
프로세스와 같이 쓰레드 또한 고유의 자원을 갖고, 흐름이 종료되면 그 자원이 자동으로 반환되지 않는다. 이를 자동으로 반납시켜주도록 예약하는 함수가 이 pthread_detach인것이다.
인자는 쓰레드이고, 리턴은 결과이다.
3. 공유 메모리의 사용과 위험, 동기화를 통한 해결
쓰레드를 사용하는 함수들에 대해서 확인해보았다. 멀티프로세스 대신 쓰레드를 사용하게 된 이유에 대해 생각해보자. 그 이유는 메모리 절약 때문이었는데, 그 절약의 비결은 메모리의 공유였다. 하지만 만약 한 쓰레드가 수정중이던 데이터를 다른 쓰레드가 접근하고 수정한다면 어떻게 될까? 그렇다면 뒤에 접근한 쓰레드는 연산 결과에 접근하는 것 대신 연산 이전의 데이터에 접근할 것이고, 이는 프로그래머의 의도와 엇나갈 수 있다. 이 영역을 critical section이라고 하자.
이를 막아주는것이 '동기화'인데, 공유 데이터의 접근을 컨트롤하여 데이터가 연산 흐름을 유지할 수 있게 해주는 것이다. 세마포어, 멀티 텍스를 통해 동기화 해줄 수 있다.
세마포어, 멀티 텍스는 다음 포스터에서 더 자세히 알아보자!
'학교 공부 > 네트워크' 카테고리의 다른 글
Multiplexing을 통한 싱글 프로세스의 다중 클라이언트 연결 (0) | 2021.04.14 |
---|---|
세마포어, 뮤텍스를 활용한 공유 자원 제어 (0) | 2021.04.14 |
멀티 프로세스를 활용한 다중 클라이언트 TCP 통신, 좀비 프로세스 삭제 (0) | 2021.04.11 |
네트워크 프로그래밍 (VM의 NAT와 Bridge, UDT) (0) | 2021.04.01 |