본문 바로가기
Computer Science

[CS] 프로세스와 스레드

by DuncanKim 2022. 7. 6.
728x90

프로세스와 스레드

 

1. 프로세스의 개념


어떤 작업을 위해 실행할 수 있는 파일을 '프로그램'이라 한다. 그 프로그램이 컴퓨터에서 연속적으로 실행될 때, 그것을 프로세스라고 한다. 메모리에 올라와서 실행되고 있는 프로그램의 인스턴스를 가리키기도 한다. 프로세스는 CPU 시간, 운영되기 위해 필요한 주소공간, code-data-stack-heap의 구조로 된 독립된 메모리 영역을 자원으로 할당받는다.

여러 프로세스를 함께 돌리는 작업은 동시적, 병렬적, 또는 이 둘의 혼합으로 이루어 진다.

동시성은 프로세서 하나가 이거 조금 하고 이거 조금 하고 이거 조금 하고, 이렇게 여러 작업을 돌아가면서 일부분씩 진행하는 것이다. 이 과정이 빠르게 돌아가면 사람들은 이 프로세스들이 동시에 진행되는 것처럼 느낄 수 있다.

병렬성은 프로세서 하나에 코어 여러 개가 달려서 각각 동시에 작업들을 수행하는 것이다. 듀얼코어 쿼드코어 옥타코어 이런 명칭이 붙는 멀티코어 프로세서가 달린 컴퓨터에서 할 수 있는 방식이다. CPU의 속도가 발열 등 물리적 제약 때문에 예전만큼 빠르게 발전하지 못하자 그 대안으로, 코어를 여러 개 달아서 작업을 분담할 수 있도록 만든 것이다.


2. 스레드의 개념


한 프로세스 내에서도 여러 갈래의 작업들이 동시에 진행될 필요가 있다. 그렇게 되면 더 빠른 실행을 할 수 있기 때문이다. 프로세스 내에서 동시성과 병렬성을 가지는 개념이라고 할 수 있겠다.
스레드는 프로세스 내에서 각각 stack만 따로 할당받고, code, data, heap 영역은 공유한다.

스레드는 한 프로세스 안에서 동작되는 여러 실행의 흐름이다. 스레드는 프로세스 내의 주소공간이나 자원들(힙, 데이터 코드)을 같은 프로세스 내에 있는 스레드끼리 공유하면서 실행된다. 각각의 스레드는 별도의 레지스터와 스택을 가지고 있지만, 힙 메모리는 서로 읽고 쓸 수 있다.
한편, 프로세스는 다른 프로세스의 메모리에 직접 접근할 수 없다.


3. 자바의 스레드

 

일반 스레드와 거의 차이가 없고, JVM이 운영체제의 역할을 한다. 자바에는 프로세스가 존재하지 않고 스레드만 존재하며, 자바 스레드는 JVM에 의해 스케줄되는 실행 단위의 코드 블록이다. 개발자는 자바 스레드로 작동할 스레드 코드를 작성하고, 스레드 코드가 생명을 가지고 실행을 할 수 있도록 JVM에 요청하는 일만 하면 된다.



<라면 끓이기 자바 코드> (from 얄팍한 코딩사전 )

import java.util.Scanner;

public class RamenProgram {
    public static void main(String[] args) {
        int num;
        Scanner input = new Scanner(System.in);
        System.out.println("라면 몇 개 끓일까요?");
        num = input.nextInt();

        System.out.println(num + "개 주문 완료! 조리시작!");
        try{
            RamenCook ramenCook = new RamenCook(num);
            new Thread(ramenCook,"A").start();
            new Thread(ramenCook,"B").start();
            new Thread(ramenCook,"C").start();
            new Thread(ramenCook,"D").start();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

interface Runnable{
    public void run();
}


class currentThread extends Thread{
    public RamenCook ramenCook;
    static String nam;

    currentThread(){
        this(new RamenCook(5) , "");
    }

    currentThread(RamenCook ramenCook , String nam){
        this.ramenCook = ramenCook;
        this.nam = nam;
    }
}


class RamenCook extends Thread implements Runnable{
    private int ramenCount;
    private String[] burners = {"_","_","_","_"};

    public RamenCook(int count){
        ramenCount = count;
    }

    @Override
    public void run(){
        while(ramenCount > 0){
            synchronized(this){
                ramenCount--;
                System.out.println(Thread.currentThread().getName() + " : " + ramenCount + "개 남았습니다");
            }

            for(int i = 0; i < burners.length; i++){
                if(!burners[i].equals("_")){
                    continue;
                }

                synchronized(this){
                    //if(burners[i].equals("_"))
                    //{
                    burners[i] = Thread.currentThread().getName();
                    System.out.println("                 " + Thread.currentThread().getName() + " : [" + (i + 1) + "]번 버너 ON");
                    showBurners();
                    //}
                }

                try {
                    Thread.sleep(2000);
                }
                catch(Exception e) {
                    e.printStackTrace();
                }

                synchronized(this) {
                    burners[i] = "_";
                    System.out.println("                                  " + Thread.currentThread().getName() + " : [" + (i + 1) + "]번 버너 OFF" );
                    showBurners();
                }
                break;
            }

            try {
                Thread.sleep(Math.round(1000 * Math.random()));
            }
            catch(Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void showBurners() {
        String stringToPrint = "                                                             ";
        for(int i = 0; i < burners.length; i++)
        {
            stringToPrint += (" " + burners[i]);
        }
        System.out.println(stringToPrint);
    }
}
728x90

댓글