운영체제 및 프로그래밍을 공부하다보면 자주 사용되는 멀티프로세싱, 멀티쓰레딩, 멀티플렉싱과 같은 단어와 각각의 장단점들에 대해 잘 정리되어있는 내용들을 모아봤다.
멀티플렉싱이란?
여러명이서 통신할때 하나의 채널만 가지고 통신하는 방식을 말한다. 멀티쓰레드, 멀티 프로세스가 여러 채널을 만들어 통신한다면 멀티플렉싱은 하나의 프로세스, 스레드를 가지고 여러 명의 통신을 연결시킨다.
여러명이 접속할 수 있는 서버를 만들기 위해 여러 IO모델들이 사용된다. 오늘은 대표적인 멀티플렉싱 방식의 IO 모델인 select에 대해 살펴보고자 한다.
1. select 동작 과정
서버는 여러 클라이언트의 접속을 받는다. 그 후 각 클라이언트의 이벤트(데이터 수신여부, 데이터 송신가능 여부, 오류 수신 여부 등)의 이벤트가 들어옴에 따라 해당 클라이언트에게 적절한 응답을 해줘야 한다.
select의 경우 먼저 FD_SET이라는 구조체를 통해 클라이언트들을 등록시킨다.
FD_SET
해당 구조체는 Linux의 경우 해당 소켓의 파일디스크립터 번호의 배열로 되어있고 윈도우의 경우 소켓의 핸들번호의 배열로 되어 있다. 구조체 관리함수는 FD_ZERO(모두 등록안됨으로 초기화) , FD_SET(해당 소켓 등록), FD_CLR(해당 소켓을 등록에서 제거), FD_ISSET(해당 소켓이 등록됬는지 확인)가 있다.
이러한 FD_SET에 들어온 클라이언트의 소켓을 등록했다면 이제 select함수를 호출해 줘야 한다.
select(파일 디스크립터 개수, 수신한 데이터가 있는 FD_SET , 송신 가능한 FD_SET, 예외발생한 FD_SET, TimeOut)을 통해 호출한다.
위에 각 이벤트 자리에 FD_SET을 인수로 등록 시키는 것은 FD_SET안에 있는 소켓들 중 해당된 이벤트가 있는지 감시하기 위한 용도로 등록시키는 것이다.
주의점은 위의 select함수에 들어간 FD_SET들이 변화된 결과(만약 수신데이터 자리에 넣어졌다면 해당 FD_SET에 수신된 데이터가 있는 소켓 자리만 1로 바뀐다.)로 초기화 되기 때문에 감시할 대상이 있는 FD_SET과 이벤트 결과가 들어갈 FD_SET을 따로 구분지어 매 루프마다(이벤트 결과를 처리한 후 마다) 감시할 대상이 있는 FD_SET을 결과 FD_SET에 복사 시켜줘야 한다는 것이다.
timeout자리에 timeval 구조체가 들어가고 시간을 설정할 수 있는데 NULL이면 FD에 변화가 생길때까지 계속 블로킹되고 시간이 설정되면 해당 시간동안 기다린 뒤 0을 반환한다. 해당 select가 반환하는 정수값은 변화된 파일디스크립터의 개수를 의미한다.
2. 장단점
가장 큰 장점은 멀티스레드, 멀티프로세스와 다르게 교착상태, 레이스 컨디션을 피하고 하나의 스레드에서 안정적으로 처리 가능하다는 점이다.
단점은 다른 IO모델과 비교하여 성능상 많은 접속을 받지 못한다. 그것엔 두가지 이유가 있는데 첫번째는 매순간 감시하고자 하는 FD_SET을 복사하여 select를 호출하는 것이다. 이 과정에서 해당 FD_SET이 커널로 넘어가게 되고 부하가 된다.
두번쨰는 내부에서 변경된 FD을 찾기위해 FD_SET을 도는 것이다. 접속자가 많아질 수록 부하가 심해진다.
이러한 이유로 인해 많은 접속이 필요한 곳엔 select를 쓸수가 없다. 하지만 많은 접속이 필요하지 않는 경우엔 select를 통해 하나의 프로세스와 스레드로 최소한의 자원사용률과 안정적으로 이벤트를 처리할 수 있다.
멀티프로세스와 멀티스레드
프로세스는 운영체제로부터 자원을 할당받는 작업의 단위이고 스레드는 프로세스가 할당받은 자원을 이용하는 실행의 단위이다.
멀티 프로세스와 멀티 스레드 사용하는 이유
멀티 스레드 vs 멀티 프로세스
- 멀티 스레드는 멀티 프로세스보다 적은 메모리 공간을 차지하고 Context Switching이 빠른 장점이 있지만, 동기화 문제와 하나의 스레드 장애로 전체 스레드가 종료 될 위험을 갖고 있다.
- 멀티 프로세스는 하나의 프로세스가 죽더라도 다른 프로세스에 영향을 주지 않아 안정성이 높지만, 멀티 스레드보다 많은 메모리공간과 CPU 시간을 차지하는 단점이 있다.
- 두 방법은 동시에 여러 작업을 수행하는 점에서 동일하지만, 각각의 장단이 있으므로 적용하는 시스템에 따라 적합한 동작 방식을 선택하고 적용해야 한다.
왜 멀티 프로세스로 할 수 있는 작업들을 굳이 하나의 프로세스에서 스레드로 나눠가며 할까?
- 운영체제가 시스템 자원을 효율적으로 관리하기 위해 스레드를 사용한다.
- 멀티 프로세스로 실행되는 작업을 멀티 스레드로 실행할 경우, 프로세스를 생성하여 자원을 할당하는 시스템 콜이 줄어들어 자원을 효율적으로 관리할 수 있다.
- 또한, 프로세스 간의 통신보다 스레드 간의 통신 비용이 적으므로 작업들 간 통신의 부담이 줄어든다. (처리비용 감소. 프로세스는 독립구조이기 때문)
그렇다면 무조건 멀티 스레드가 좋을까?
- 스레드를 활용하면 자원의 효율성이 증가하기도 하지만, 스레드 간의 자원 공유는 전역 변수를 이용하므로 동기화 문제가 발생 할 수 있으므로 프로그래머의 주의가 필요하다.
멀티 프로세스(Multi Process)
개념
- 두개 이상 다수의 프로세서(CPU)가 협력적으로 하나 이상의 작업(Task)을 동시에 처리하는 것이다. (병렬처리)
- 각 프로세스 간 메모리 구분이 필요하거나 독립된 주소 공간을 가져야 할 경우 사용한다.
장점
- 독립된 구조로 안전성이 높은 장점이 있다.
- 프로세스 중 하나에 문제가 생겨도 다른 프로세스에 영향을 주지 않아, 작업속도가 느려지는 손해정도는 생기지만 정지되거나 하는 문제는 발생하지 않는다.
- 여러개의 프로세스가 처리되어야 할 때 동일한 데이터를 사용하고, 이러한 데이터를 하나의 디스크에 두고 모든 프로세서(CPU)가 이를 공유하면 비용적으로 저렴하다.
문제점
- 독립된 메모리 영역이기 때문에 작업량이 많을수록( Context Switching이 자주 일어나서 주소 공간의 공유가 잦을 경우) 오버헤드가 발생하여 성능저하가 발생 할 수 있다.
- Context Switching 과정에서 캐시 메모리 초기화 등 무거운 작업이 진행되고 시간이 소모되는 등 오버헤드가 발생한다.
Context Switching
- CPU는 한번에 하나의 프로세스만 실행 가능하다.
- CPU에서 여러 프로세스를 돌아가면서 작업을 처리하는 데 이 과정을 Context Switching라 한다.
- 구체적으로, 동작 중인 프로세스가 대기를 하면서 해당 프로세스의 상태(Context)를 보관하고, 대기하고 있던 다음 순서의 프로세스가 동작하면서 이전에 보관했던 프로세스의 상태를 복구하는 작업을 말한다.
멀티 스레드(Multi Thread)
개념
- 하나의 프로세스에 여러 스레드로 자원을 공유하며 작업을 나누어 수행하는 것이다.
장점
- 시스템 자원소모 감소 (자원의 효율성 증대)
- 프로세스를 생성하여 자원을 할당하는 시스템 콜이 줄어 자원을 효율적으로 관리할 수 있다.
- 시스템 처리율 향상 (처리비용 감소)
- 스레드 간 데이터를 주고 받는 것이 간단해지고 시스템 자원 소모가 줄어든다.
- 스레드 사이 작업량이 작아 Context Switching이 빠르다. (캐시 메모리를 비울 필요가 없다.)
- 간단한 통신 방법으로 프로그램 응답시간 단축
- 스레드는 프로세스 내 스택영역을 제외한 메모리 영역을 공유하기에 통신 비용이 적다.
- 힙 영역을 공유하므로 데이터를 주고 받을 수 있다.
문제점
- 자원을 공유하기에 동기화 문제가 발생할 수 있다. (병목현상, 데드락 등)
- 주의 깊은 설계가 필요하고 디버깅이 어렵다. (불필요 부분까지 동기화하면, 대기시간으로 인해 성능저하 발생)
- 하나의 스레드에 문제가 생기면 전체 프로세스가 영향을 받는다.
- 단일 프로세스 시스템의 경우 효과를 기대하기 어렵다.
출처 :
https://dhdnjswo5000.tistory.com/41
https://wooody92.github.io/os/%EB%A9%80%ED%8B%B0-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EB%A9%80%ED%8B%B0-%EC%8A%A4%EB%A0%88%EB%93%9C/
'Development > Network' 카테고리의 다른 글
[Windows Socket] - Client (0) | 2022.09.08 |
---|---|
[Windows Socket] - Server (0) | 2022.09.08 |
[Windows Socket] - 시작하기 (0) | 2022.09.08 |