Network/소켓통신(Linux)

멀티스레드 개념

busy맨 2023. 11. 19. 21:20

1. 스레드 기초

1) 소켓 응용 프로그램과 멀티스레드

  • 멀티스레드를 사용하지 않는 경우 문제
    • 두 개 이상의 클라이언트가 서버에 접속할 수 있으나, 서버가 동시에 두 개 이상의 클라이언트를 서비스 할 수
      없음
    • 서버와 클라이언트의 send()와 recv() 호출 순서가 서로 맞아야함
    • 데이터를 보내지 않은 상태에서 양쪽에서 동시에 recv()를 호출하면 교착상태(Deadlock)가 발생
      • 교착상태란 영원히 일어나지 않을 사건을 기다리는 상황
      • recv()에서 빠져나가지 못하고 send() 를 호출할 수 없어 교착상태가 발생
  • 다중 처리 문제 해결책
    1. 서버가 각 클라이언트와 연결하여 통신하는 시간을 짧게 줄임
      • 클라이언트가 데이터를 전송하기 전에 매번 서버에 접속하고, 전송 후에는 곧바로 접속을 끊는 방식
      • 특별한 기법을 도입하지 않고 쉽게 구현 가능하고, 서버의 시스템 자원을 적게 사용
      • 파일 전송 프로그램과 같이 대용량 데이터를 전송하는 응용 프로그램을 구현하기에 적합 X
      • 클라이언트 수가 많으면 처리 지연 시간이 길어짐
    2. 서버에 접속한 클라이언트마다 스레드를 생성하여 독립적으로 처리
      • 소켓 입출력 모델에 비해 쉽게 구현
      • 접속한 클라이언트 수에 비례하여 스레드를 생성하므로 서버의 시스템 자원을 많이 사용
    3. 소켓 입출력 모델 사용
      • 소수의 스레드를 이용하여 다수의 클라이언트를 처리 가능
      • 위의 두 방법보다 구현이 어려움
  • 교착 상태 발생 해결책
    1. 데이터 송수신 부분을 잘 설계하여 교착 상태가 발생하지 않도록 함
      • 특별한 기법을 도입하지 않고도 구현 가능
      • 데이터 송수신 패턴이 달라지면 교착 상태가 발생
    2. 소켓에 타임아웃(Timeout) 옵션을 적용하여, 소켓 함수 호출 시 작업이 완료되지 않아도 일정 시간 후에 리턴하게 함
      • 비교적 간단하게 구현 가능
      • 타임아웃으로 지정한 시간이 지날 때까지 아무것도 할 수 없기 때문에 다른 방법보다 성능이 떨어짐
    3. 넌블로킹(Nonblocking) 소켓을 사용
      • 넌블로킹 소켓을 사용하면 조건을 만족하지 않더라도 소켓 함수가 즉시 리턴하여 교착상태 방지
      • 구현이 복잡하고 불필요하게 CPU 시간을 낭비할 수 있음
    4. 소켓 입출력 모델 사용
      • 넌블로킹 소켓 방식의 단점을 보완하며 교착상태 방지
      • 구현이 어려움

 

2) 스레드 기본 개념

  • 프로세스(Process)
    • CPU 시간을 할당받아 실행 중인 프로그램
    • 프로그램(Program)이 저장 장치에 실행 파일로 존재하는 정적인 개념에 반해,
      프로세스는 코드(CPU 명령), 데이터(전역 변수, 정적 변수), 리소스(그림 파일, 사운드 파일 등)를 파일에서 읽어들여 작업을 수행하는 동적인 개념임
  • 윈도우 운영체제에서 일반적인 의미의 프로세스의 개념은 프로세스 + 스레드 두 가지로 구분
    • 프로세스는 코드, 데이터, 리소스를 파일에서 읽어들여 메모리 영역에 담고 있는 일종의 컨테이너(Container)
    • 스레드(Thread)는 CPU 시간을 할당방다 프로세스 메모리 영역에 있는 코드를 수행하고 데이터를 사용하는
      실행 흐름
  • 멀티스레드 응용 프로그램(Multithreaded Application)
    • 응용 프로그램 실행 시 최초로 생성되는 스레드는 주 스레드(Primary Thread) 또는 메인 스레드(Main Thread)
    • 만약 응용 프로그램에서 메인 스레드와 별도로 동시에 수행하고자 하는 작업이 있다면 스레드 추가 생성
  • 멀티스레드 동작 과정
    • CPU 하나가 스레드 두 개를 동시에 실행할 수는 없어도 교대로 실행하는 일은 가능
      • 교대로 실행하는 간격이 짧을 때, 사용자는 두 스레드가 동시에 실행되는 것처럼 느낌
    • 스레드의 최종 실행 상태를 저장하고 나중에 복원하는 작업을 반복
      • 스레드의 실행 상태란 CPU 레지스터와 메모리의 스택을 의미
    • 스레드 실행 상태의 저장과 복원 작업을 컨덱스트 전환(Context Switch)라고 함
      • 이를 통해 각 스레드가 서로의 존재와 무관하게 실행 상태를 유지

  1. 스레드 1이 실행 중
    명령을 하나 수행할 때마다 CPU 레지스터 값과 메모리의 스택 내용이 변경됨
  2. 스레드 1의 실행을 중지하고 실행 상태를 저장
    이전에 저장해둔 스레드 2의 상태를 복원
  3. 스레드 2 실행
    명령을 하나 수행할 때마다 CPU 레지스터 값과 메모리의 스택 내용이 변경됨
  4. 스레드 2의 실행을 중지하고 실행 상태를 저장
    이전에 저장해둔 스레드 1의 상태를 복원
  5. 위 과정 반복

'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