본문 바로가기
전공 수업/컴퓨터 통신(Computer Communication)

[10주 차] - 프로세스와 스레드(Process and Thread), 멀티 스레드(Multi-thread)

by TwoJun 2022. 11. 6.

    과목명 : 컴퓨터 통신(Computer communication)

수업일자 : 2022년 10월 31일 (월)

 

 

 

 

1. TCP 서버 - 클라이언트의 문제점 

1-1. 문제점 (1) 

- 동시에 두 이상의 클라이언트 서비스는 불가능합니다.

 

 

 

1-2. 문제점 (1)에 대한 해결 방안

(1) 서버가 각 클라이언트와 통신하는 시간을 짧게 줄입니다.

장점 : 구현하기 쉽고 가장 적은 시스템 자원을 사용합니다.

단점 : 각 클라이언트의 처리 지연 시간이 길어질 수 있습니다.

 

(2) 각 클라이언트의 스레드(Thread)를 이용해 독립적으로 처리합니다.

장점 : 소켓 입/출력 모델에 비해 구현이 쉽습니다.

단점 : 가장 많은 시스템 자원을 사용하게 됩니다.

 

(3) 소켓 입출력 모델을 사용합니다.

장점 : 소수의 스레드를 이용해 다수의 클라이언트를 처리합니다. (상대적으로 적은 시스템 자원 사용)

단점 : 구현이 어려운 편입니다.

 

 

 

 

1-3. 문제점 (2)

- 교착 상태(Deadlock)가 발생할 수 있습니다.

- 교착 상태(Deadlock)의 정의 : 두 개 이상의 작업이 서로 상대방의 작업이 끝나기만을 기다리고 있기 때문에 결과적으로 아무것도 완료되지 못하는 상태를 의미합니다.

 

 

 

 

 

1-4. 문제점 (2)에 대한 해결 방안

(1) 데이터 송/수신 부분을 잘 설계합니다.

장점 : 특별한 기법 없이 곧바로 구현이 가능합니다.

단점 : 모든 경우에 대한 해결책이 될 수는 없습니다.

 

(2) 소켓에 타임아웃 옵션을 적용합니다.

장점 : 구현이 쉬운 편입니다.

단점 : 다른 방법에 비해 성능이 낮습니다.

 

(3) Non-Blocking 소켓을 사용합니다.

장점 : 근본적으로 교착 상태를 해결할 수 있습니다.

단점 : 구현이 어려우며, 시스템 자원이 낭비됩니다.

 

(4) 소켓 입/출력 모델을 사용합니다.

장점 : Non-Blocking 소켓의 단점을 보완하며 교착 상태를 해결할 수 있습니다.

단점 : 첫 번째나 두 번째 해결책보다 구현이 어려운 편입니다.

 

 

 

 

 

2. 프로세스와 스레드(Process and Thread)

2-1. 프로세스(Process)의 정의

- 프로세스(Process)란, 컴퓨터에서 실행되고 있는 연속적인 프로그램의 인스턴스(독립적인 개체)입니다.

 

- 프로세스는 코드, 데이터, 리소스를 파일에서 읽어들여 운영체제가 할당해 놓은 메모리 영역에 담고 있는 일종의 컨테이너(Container)로, 정적인 개념으로 정의할 수 있습니다.

 

- 프로그램 실행을 위해 운영체제로부터 자원을 할당는 작업의 단위를 의미하기도 합니다.

 

- 컴퓨터의 하드 디스크나 SSD와 같은 저장 장치(Storage device)에 저장된 프로그램의 소스코드와 정적 데이터가 메모리에 적재되어 실행 중 상태가 되면 프로세스로 동작하게 됩니다.

 

- 여기서 프로그램(Program)과 프로세스(Process)는 명확한 차이를 갖습니다.  프로그램은 사용자의 목적에 맞게 연산 및 작업을 수행하기 위한 코드 및 데이터들의 집합체이고 프로세스는 해당 집합체가 메모리에 적재되어 실행되는 프로그램을 의미합니다. 

 

 

 

 

2-2. 스레드(Thread)의 정의 

- 프로세스 내부에서 실행되는(코드가 실행되는) 여러 흐름의 단위입니다.

 

- 프로세스의 특정한 수행 경로이며, 프로세스가 할당받은 자원을 이용하는 실행의 단위입니다.

 

- 응용 프로그램 실행 시 최초로 실행되는 스레드를 주 스레드(Main thread)라고 하며 만약 프로그램에서 주 스레드와 별개로 동시에 수행하고자 하는 작업이 있다면 스레드를 추가로 생성하여 스레드가 작업을 수행하게 하면 됩니다. 이를 멀티스레드 응용 프로그램(Multithreaded application)이라고 합니다.

 

 

 

 

2-3. 멀티스레드(Multi-thread)

- 하나의 프로세스 내에서 둘 이상의 스레드가 동시에 작업을 수행하는 것을 의미합니다.

 

- 멀티 스레드는 각 자신이 속한 프로세스의 메모리를 함께 공유하며 작업을 수행하게 됩니다.

 

 

 

 

2-4. 컨텍스트 스위칭(Context Switching)

- CPU는 두 개의 작업을 동시에 처리할 수는 없지만 교대로 실행하는 것은 가능하며 교대로 실행되는 시간이 충분히 짧다면 사용자는 두 스레드가 동시에 실행되는 것처럼 생각할 수 있게 됩니다.

 

- 이러한 방법은 반드시 각 스레드의 최종 실행 상태를 저장하고 나중에 복원하는 작업이 필요합니다.

 

- CPU와 운영체제가 동시에 동작하여 이러한 스레드의 실행 상태의 저장, 복원 작업을 컨텍스트 스위칭(Context Switching)이라고 합니다.

 

- 아래 동작 구조 이미지는 프로세스 하나가 스레드 두 개를 사용하는 원리입니다.

컨텍스트 스위칭(Context Switching)

 

 

 

 

 

3. 스레드의 생성과 종료

3-1. 스레드 생성에 필요한 요소

(1) 스레드 함수의 시작 주소

(2) 스레드 함수 실행 시 사용할 스택의 크기

 

- 일반 함수 내부엔 무한 루프가 존재할 수 없습니다.

 

- 스레드 함수 내부엔 무한 루프가 존재할 수 있습니다.

스레드가 호출되어도 기존 메인 함수는 지속적으로 수행되는 병렬적(Parallel) 흐름이 수행되기 때문입니다.

함수 두 개로 구성된 응용 프로그램에 스레드 세 개가 존재하는 경우

 

 

 

 

3-2. 스레드 생성 - CreateThread() 함수 - (Win32 API 기준)

- 스레드를 생성한 후 스레드 핸들을 리턴합니다.

 

createThread() 함수를 이용한 Thread 생성

 

HANDLE CreateThread( 
    LPSECURITY_ATTRIBUTESlpThreadAttributes,    // NULL
    SIZE_T dwStackSize,    // 0
    LPTHREAD_START_ROUTINElpStartAddress     // 스레드 함수
    LPVOID lpParameter,    // 스레드 함수에 전달할 인자
    DWORD dwCreationFlags,    // 0 또는 CREATE_SUSPENDED
    LPDWORD lpThreadId    // 스레드 ID
};

(1) lpThreadAttributes

- 핸들 상속(Handle inheritance)과 보안 디스크립터 정보를 전달합니다.

- NULL 값을 이용하면 스레드를 생성하고 사용할 수 있습니다.

 

(2) dwStackSize

- 스레드에 할당되는 스택의 크기입니다. 0을 사용하면 실행 파일 헤더의 기본 크기를 이용합니다.

 

(3) lpStartAddress

- 스레드 함수의 시작 주소입니다.

- 스레드 함수는 반드시 다음과 같은 형태로 정의되어야 합니다.

- Double word로 리턴값을 가지며, WINAPI는 함수 호출 규약입니다.

DWORD WINAPI ThreadProc(LPVOID lpParameter) {
...
}

 

(4) lpParameter

- 스레드 함수에 전달할 인자를 입니다.

 

(5) dwCreationFlags

- 스레드 생성을 제어하는 값입니다.

 

 

 

 

 

3-3. 스레드 종료 방법

(1) 스레드 함수가 리턴하면 스레드가 종료됩니다.

(2) 스레드 함수 내에서 ExitThread() 함수를 호출하면 스레드가 종료됩니다.

(3) 다른 스레드가 TerminateThread() 함수를 호출하면 스레드가 종료됩니다.

(4) 주 스레드(Main 스레드)가 종료되면 모든 스레드가 종료됩니다.

- 각 스레드의 작업을 모두 완료하려면 Main 스레드가 종료되지 않아야 합니다.

 

메인 스레드가 종료되면 기존에 실행되던 모든 스레드는 종료된다.

 

 

 

 

3-4. 스레드 종료 함수 

(1) void ExitThread()

void ExitThread(
    DWORD dwExitCode    // 종료 코드
);

 

 

(2) BOOL TerminateThread()

BOOL TerminateThread(
    HANDLE hThread,      // 종료할 스레드를 기다리는 핸들
    DWORD dwExitCode,    // 종료 코드 
);

 

 

 

 

 

 

- 학부에서 수강했던 전공 수업 내용을 정리하는 포스팅입니다.

- 내용 중에서 오타 또는 잘못된 내용이 있을 시 지적해 주시기 바랍니다.

댓글