본문 바로가기
Computer Science

[CS] Multi Process, Multi Thread 개념과 구현

by DuncanKim 2022. 7. 31.
728x90

[CS] Multi Process, Multi Thread

 

 

프로세스와 스레드에 대해서는 이전에 한 번 정리를 한 적이 있다.

 

2022.07.06 - [IT 지식/CS] - [CS] 프로세스와 스레드

 

[CS] 프로세스와 스레드

프로세스와 스레드 1. 프로세스의 개념 어떤 작업을 위해 실행할 수 있는 파일을 '프로그램'이라 한다. 그 프로그램이 컴퓨터에서 연속적으로 실행될 때, 그것을 프로세스라고 한다. 메모리에 올

masterpiece-programming.tistory.com

 

하지만 개념적인 측면에서 프로세스가 무엇인지, 스레드가 무엇인지 정도만 정리를 했기 때문에, 지금 와서 스레드를 사용한 프로그램을 구현하라고 하면...? 말하는 감자에 불과해진다. 그래서 프로그래머스 자바 중급 강의와 여러 참고 자료들을 보면서 스레드를 어떻게 구현하는지, 그리고 멀티 프로세스와 멀티 스레드가 무엇인지 알아보고자 한다.

 

 

1. 개념 정리

 

프로그램(program)
: 어떤 작업에 기본이 되는 실행할 수 있는 코드, 파일.

실행 단위
: 프로세스와 스레드를 포괄하는 개념. cpu core에서 실행하는 하나의 단위

프로세스(process)
: 컴퓨터에서 연속적으로 실행되고 있는 '프로그램'. 메모리에 올라와 실행되고 있는 프로그램의 '인스턴스' (실행된 프로그램)

스레드
: 프로세스 안에서 실행되는 여러 흐름의 단위. 프로세스가 할당받은 자원을 이용하는 실행의 단위.

멀티 프로세스
: 하나의 프로그램을 여러 개의 프로세스로 구성하여 각 프로세스가 병렬적으로 작업을 수행하는 것.

멀티 스레드
: 하나의 응용 프로그램에서 여러 스레드를 구성해서 각 스레드가 하나의 작업을 처리하는 것.

동시성
: 한 순간에 여러 가지 일이 처리되는 것이 아니라, 짧은 전환으로 여러 가지 일을 동시에 처리하는 것처럼 보이는 것.
ex. 여러 가지 프로세스를 동시에 실행할 때, 시분할로 짧은 텀을 반복하면서 순간 순간 전환을 하는 방법으로 여러 가지를 돌리는 효과를 내주는 것이다. 

병렬성
: 프로세서 하나에 여러 코어가 작업을 분담하여 처리하는 것.

컨텍스트 스위칭
: 하나의 프로세스가 이미 CPU를 사용 중인 상태에서 다른 프로세스가 CPU를 사용하기 위해 이전 프로세스의 상태를 저장하고 새로운 프로세스의 상태를 적재하는 것.

 

 

2. Thread 만들기

 

자바에서 thread를 만드는 방법은 Thread 클래스를 상속하는 방법과 Runnable 인터페이스를 구현하는 방법이 있다.

 

1) Thread 클래스를 상속하는 방법

 

Thread 클래스를 상속하여 run() 메서드를 재정의 하는 방식으로 스레드를 구현한 것이다.

class MyThread1 extends Thread {
    String str;
    public MyThread1(String str){
        this.str = str;
    }

    public void run(){
        for(int i = 0; i < 10; i ++){
            System.out.print(str);
            try {
                //컴퓨터가 너무 빠르기 때문에 수행결과를 잘 확인 할 수 없어서 Thread.sleep() 메서드를 이용해서 조금씩 
                //쉬었다가 출력할 수 있게한다. 
                Thread.sleep((int)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } 
    } 
}
    
public class ThreadExam1 {
    public static void main(String[] args) {
        // MyThread인스턴스를 2개 만듭니다. 
        MyThread1 t1 = new MyThread1("*");
        MyThread1 t2 = new MyThread1("-");

        t1.start();
        t2.start();
        System.out.print("!!!!!");  
    }   
}

코드를 구현하면 다음과 같은 결과를 얻을 수 있다.

*과 -가 번갈아가면서 나오는 것을 볼 수 있는데, !!!!!의 경우, 코드라인 상으로 가장 마지막에 있음에도 *가 한 번 등장하고 바로 나오는 것을 볼 수 있다. 랜덤으로 sleep()을 걸어주었기 때문인데, 수행 흐름이 여러 개로 나누어지고, 각자의 sleep() 시간에 맞추어서 print가 되어 나오는 결과가 저것이라고 보면 된다.

 

현재는 콘솔창에서 thread가 여러 개로 나누어져 있을 때, 어떻게 함수를 호출하는지 알아보는 것에 불과하지만, 이것이 어떤 어플리케이션의 일부 실행 흐름이라고 보면 더 이해를 하기 쉬울 것 같다. 여러 개의 브라우저 창을 띄워놓고 웹 서핑을 할 때 일어나는 일을 상상해보자. 각각의 창은 다른 페이지의 정보들을 담고 있는 별개의 '스레드'라고 볼 수 있다. 그 창을 열어서 실행하면 그 페이지의 정보를 사용자에게 보여준다. 이 경우 다른 스레드는 실행될 필요가 없다. 현재 내가 보고 있는 창만 실행이 되면 된다. 어느 창은 실행이 되고, 실행이 되지 않는 상황을 반복하면서 우리는 여러 개의 창을 켜놓고 검색을 할 수 있는 것이다.

 

 

2) Runnable Interface를 구현하는 방법

 

Runnable 인터페이스가 가지고 있는 run() 메서드를 구현한다.

자바는 단일 상속만을 허용하기 때문에, 만약 상속받은 클래스가 있는 클래스에 스레드를 구현하고 싶다면, Runnable 인터페이스를 구현하는 방식으로 스레드를 구현하면 된다.

 

class MyThread2 implements Runnable {
    String str;
    public MyThread2(String str){
        this.str = str;
    }

    public void run(){
        for(int i = 0; i < 10; i ++){
            System.out.print(str);
            try {
                Thread.sleep((int)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } 
    } 
}

public class ThreadExam2 {  
    public static void main(String[] args) {
        MyThread2 r1 = new MyThread2("*");
        MyThread2 r2 = new MyThread2("-");

        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);

        t1.start();
        t2.start();
        System.out.print("!!!!!");  
    }   
}

 

 

3. 멀티 프로세스, 멀티 스레드

 

 

동시에 무엇인가를 처리한다는 그 말. 뭔가 느낌은 오지만, 실제 내가 구현해야 하는 프로그램에서 어떻게 처리되는지, 어떻게 보여지는 지를 쉽게 상상을 할 수가 없었다. 그렇지만, 조금씩 알아가다 보니 멀티 프로세스와 멀티 스레드는 매번 웹 브라우저에서 경험하는 기술이라는 것을 알 수 있었다.

 

우리가 어떤 게시판 페이지를 들어간다고 하자. 그 페이지가 엄청 많은 정보들을 담고 있는데, 우리집 공유기가 성능이 너무 느리다면...? '로딩' 시간이 길어질 수밖에 없다. 그런데, 텍스트로만 되어 있는 상단 네비게이션 메뉴바는 금방 뜰 수 있다. 메뉴바가 먼저 뜨고, 그 안에 게시물들은 천천히 뜨고 있는 것을 볼 수 있는데, 이를 멀티 스레드 처리방식과 비슷하다고 보면 될 것 같다.

 

네비게이션 메뉴바가 뜨는 코드와 게시물이 뜨는 코드는 각각의 스레드로 처리되고 있는 것이다. 

 

이렇게 추상적인 개념으로 이해를 하고, 멀티 프로세스와 스레드의 각각의 개념과 차이점, 구현 예시들을 살펴보았다.

 

 

1) 멀티 프로세스

: 하나의 프로그램을 여러 개의 프로세스로 구성하여 각 프로세스가 병렬적으로 작업을 수행하는 것.

 

웹 브라우저 중 크롬은 여러 개의 멀티 탭을 띄울 때, 각각의 프로세스로 창을 띄운다. 크롬이라는 프로세스 안에 여러 개의 탭이라는 자식 프로세스가 존재하는 것이다. 한편, 故 인터넷 익스플로러의 경우, 멀티 스레드 방식으로 멀티 탭을 띄우는데, 둘 사이의 차이점을 알아보면 두 방식의 차이를 알 수 있다.

 

 

(1) 멀티 프로세스의 장점

 

- 여러 개의 자식 프로세스 중에 하나가 문제가 발생하면, 그 문제가 발생한 프로세스만 다운되고, 나머지에는 영향을 미치지 않는다.

 

: 즉, 일부 프로세스에 문제가 있어도 전체에는 영향을 끼치지 않아 프로그램 안정성에 도움이 된다. 크롬의 경우, 하나의 창에 문제가 있어도, 크롬이라는 프로세스가 갑자기 전부 꺼져버리지는 않는다.

 

 

(2) 멀티 프로세스의 단점

 

- context switching 과정에서 캐시 메모리 초기화 등 무거운 작업이 진행되고, 시간이 많이 소모되는 등 오버헤드가 발생한다.

- 프로세스 사이에 어렵고 복잡한 통신 기법을 사용한다(IPC)

- 시스템 자원을 많이 소모할 수밖에 없다.

 

cf) context switching : CPU에서 여러 프로세스를 돌아가면서 작업을 처리하는 과정. 동작 중인 프로세스가 대기하면서 해당 프로세스의 상태(context)를 보관하고, 대기하고 있던 다음 순서의 프로세스가 동작하면서 이전에 보관했던 프로세스의 상태를 복구하는 작업.

 

2) 멀티 스레드


: 하나의 응용 프로그램에서 여러 스레드를 구성해서 각 스레드가 하나의 작업을 처리하는 것.

: 윈도우, 리눅스 등의 많은 운영체제들이 멀티 스레딩을 기본으로 지원하고 있다.

 

 

(1) 멀티 스레드의 장점

 

- 시스템 자원 소모 감소, 시스템 처리량 증가(자원의 효율성 증대, 처리 비용 감소)

: 스레드 간 데이터를 주고받는 것이 간단해지고, 프로세스를 생성하여 자원을 할당하는 시스템 요청, 응답이 줄어서 자원을 효율적으로 관리할 수 있다.

 

- 간단한 통신 방법으로 인한 프로그램 응답 시간 단축

: 스레드는 프로세스 내의 스택 영역을 제외한 모든 메모리를 공유하기 때문에 통신의 부담이 적다. 

 

 

(2) 멀티 스레드의 단점

 

- 단일 프로세스 시스템일 경우, 장점과 같은 효과를 기대하기 어렵다.

- 다른 프로세스에서 스레드를 제어할 수 없다.

- 멀티 스레드의 경우 자원 공유에서 동기화 문제가 발생한다.

- 하나의 스레드에 문제가 발생하면 전체 프로세스가 영향을 받는다.

- 주의 깊은 설계가 필요하며, 디버깅이 까다롭다.

 

 

 

4. 정리

 

프로세스는 프로그램이 실행된 것이고, 스레드는 한 프로세스 안에서 나뉜 하나 이상의 실행 단위이다.
한 어플리케이션에 대한 작업을 동시에 하기 위해서는 2가지 처리 방식(멀티 프로세스, 멀티 스레드)이 있다.
동시에 실행이 되는 것처럼 보이기 위해서 실행 단위는 시분할로 CPU를 점유하며 context switching을 한다.
멀티 프로세스는 독립적인 메모리를 가지고 있지만 멀티 스레드는 자원을 공유한다. 그것에 따른 각각의 장단점이 있다.

 

 

 

 

 

<참고>
https://school.programmers.co.kr/learn/courses/9
https://www.youtube.com/watch?v=1grtWKqTn50&list=PLE0hRBClSk5Lcgv3c-I3PH-1LGkv96oYN&index=39

 

 

 

 

728x90

댓글