1. 스레드 기초
1) 소켓 응용 프로그램과 멀티스레드
- 멀티스레드를 사용하지 않는 경우 문제
- 두 개 이상의 클라이언트가 서버에 접속할 수 있으나, 서버가 동시에 두 개 이상의 클라이언트를 서비스 할 수
없음 - 서버와 클라이언트의 send()와 recv() 호출 순서가 서로 맞아야함
- 데이터를 보내지 않은 상태에서 양쪽에서 동시에 recv()를 호출하면 교착상태(Deadlock)가 발생
- 교착상태란 영원히 일어나지 않을 사건을 기다리는 상황
- recv()에서 빠져나가지 못하고 send() 를 호출할 수 없어 교착상태가 발생
- 두 개 이상의 클라이언트가 서버에 접속할 수 있으나, 서버가 동시에 두 개 이상의 클라이언트를 서비스 할 수
- 다중 처리 문제 해결책
- 서버가 각 클라이언트와 연결하여 통신하는 시간을 짧게 줄임
- 클라이언트가 데이터를 전송하기 전에 매번 서버에 접속하고, 전송 후에는 곧바로 접속을 끊는 방식
- 특별한 기법을 도입하지 않고 쉽게 구현 가능하고, 서버의 시스템 자원을 적게 사용
- 파일 전송 프로그램과 같이 대용량 데이터를 전송하는 응용 프로그램을 구현하기에 적합 X
- 클라이언트 수가 많으면 처리 지연 시간이 길어짐
- 서버에 접속한 클라이언트마다 스레드를 생성하여 독립적으로 처리
- 소켓 입출력 모델에 비해 쉽게 구현
- 접속한 클라이언트 수에 비례하여 스레드를 생성하므로 서버의 시스템 자원을 많이 사용
- 소켓 입출력 모델 사용
- 소수의 스레드를 이용하여 다수의 클라이언트를 처리 가능
- 위의 두 방법보다 구현이 어려움
- 서버가 각 클라이언트와 연결하여 통신하는 시간을 짧게 줄임
- 교착 상태 발생 해결책
- 데이터 송수신 부분을 잘 설계하여 교착 상태가 발생하지 않도록 함
- 특별한 기법을 도입하지 않고도 구현 가능
- 데이터 송수신 패턴이 달라지면 교착 상태가 발생
- 소켓에 타임아웃(Timeout) 옵션을 적용하여, 소켓 함수 호출 시 작업이 완료되지 않아도 일정 시간 후에 리턴하게 함
- 비교적 간단하게 구현 가능
- 타임아웃으로 지정한 시간이 지날 때까지 아무것도 할 수 없기 때문에 다른 방법보다 성능이 떨어짐
- 넌블로킹(Nonblocking) 소켓을 사용
- 넌블로킹 소켓을 사용하면 조건을 만족하지 않더라도 소켓 함수가 즉시 리턴하여 교착상태 방지
- 구현이 복잡하고 불필요하게 CPU 시간을 낭비할 수 있음
- 소켓 입출력 모델 사용
- 넌블로킹 소켓 방식의 단점을 보완하며 교착상태 방지
- 구현이 어려움
- 데이터 송수신 부분을 잘 설계하여 교착 상태가 발생하지 않도록 함
2) 스레드 기본 개념
- 프로세스(Process)
- CPU 시간을 할당받아 실행 중인 프로그램
- 프로그램(Program)이 저장 장치에 실행 파일로 존재하는 정적인 개념에 반해,
프로세스는 코드(CPU 명령), 데이터(전역 변수, 정적 변수), 리소스(그림 파일, 사운드 파일 등)를 파일에서 읽어들여 작업을 수행하는 동적인 개념임
- 윈도우 운영체제에서 일반적인 의미의 프로세스의 개념은 프로세스 + 스레드 두 가지로 구분
- 프로세스는 코드, 데이터, 리소스를 파일에서 읽어들여 메모리 영역에 담고 있는 일종의 컨테이너(Container)
- 스레드(Thread)는 CPU 시간을 할당방다 프로세스 메모리 영역에 있는 코드를 수행하고 데이터를 사용하는
실행 흐름
- 멀티스레드 응용 프로그램(Multithreaded Application)
- 응용 프로그램 실행 시 최초로 생성되는 스레드는 주 스레드(Primary Thread) 또는 메인 스레드(Main Thread)
- 만약 응용 프로그램에서 메인 스레드와 별도로 동시에 수행하고자 하는 작업이 있다면 스레드 추가 생성
- 멀티스레드 동작 과정
- CPU 하나가 스레드 두 개를 동시에 실행할 수는 없어도 교대로 실행하는 일은 가능
- 교대로 실행하는 간격이 짧을 때, 사용자는 두 스레드가 동시에 실행되는 것처럼 느낌
- 스레드의 최종 실행 상태를 저장하고 나중에 복원하는 작업을 반복
- 스레드의 실행 상태란 CPU 레지스터와 메모리의 스택을 의미
- 스레드 실행 상태의 저장과 복원 작업을 컨덱스트 전환(Context Switch)라고 함
- 이를 통해 각 스레드가 서로의 존재와 무관하게 실행 상태를 유지
- CPU 하나가 스레드 두 개를 동시에 실행할 수는 없어도 교대로 실행하는 일은 가능
- 스레드 1이 실행 중
명령을 하나 수행할 때마다 CPU 레지스터 값과 메모리의 스택 내용이 변경됨 - 스레드 1의 실행을 중지하고 실행 상태를 저장
이전에 저장해둔 스레드 2의 상태를 복원 - 스레드 2 실행
명령을 하나 수행할 때마다 CPU 레지스터 값과 메모리의 스택 내용이 변경됨 - 스레드 2의 실행을 중지하고 실행 상태를 저장
이전에 저장해둔 스레드 1의 상태를 복원 - 위 과정 반복
'Network > 소켓통신(Linux)' 카테고리의 다른 글
멀티스레드 : 리눅스 2 (1) | 2023.11.19 |
---|---|
멀티스레드: 리눅스 1 (1) | 2023.11.19 |
TCP 동작 과정 및 함수 정리 (0) | 2023.11.19 |
데이터 전송하기 (0) | 2023.09.17 |
TCP 서버 - 클라이언트 구조 (2) | 2023.09.02 |