-
Notifications
You must be signed in to change notification settings - Fork 0
2주차 월요일 그룹 5
Park minji edited this page Jul 1, 2024
·
7 revisions
- 메모리에 올라간 실행 중인 프로그램
- 메모리에 올라오면 메모리의 운영체제 영역에 PCB가 만들어진다. 문맥 교환 시 PCB에 작업 내용을 저장하고, 복원한다.
- 실행 중인 컴퓨터 프로그램의 인스턴스
프로세스 구성 요소
- 독립된 메모리 공간(가상 주소 공간)
- 운영 체제에서 할당한 시스템 리소스
- 프로그램 코드
- 데이터
- 하나 이상의 실행 스레드(주로 메인 스레드라고도 함)
프로세스의 주요 특징
- 다른 프로세스로부터 격리됨
- 자신만의 기억공간을 가지고 있다
- 생성하고 종료하려면 더 많은 리소스가 필요합니다.
- 프로세스 간 컨텍스트 전환 속도가 느려짐
- 프로세스 간 통신이 더 복잡해졌습니다.
- cpu에서 실행 중인 프로세스의 실행 단위
- 실행을 예약할 수 있는 프로세스의 간단한 하위 집합입니다.
- 동일한 프로세스의 다른 스레드와 동일한 메모리 공간 및 리소스를 공유합니다.
- 생성 및 종료에 필요한 리소스가 더 적습니다.
- 스레드 간 컨텍스트 전환이 더 빨라졌습니다.
- 동일한 프로세스 내의 스레드 간 통신이 더 쉬워졌습니다.
- 단일 프로세스 내에 여러 스레드가 존재할 수 있습니다.
- 프로세스의 PCB와 같이 스레드의 상태를 저장하기 위한 TCB를 가집니다.
- 리소스 사용량: 프로세스는 스레드보다 리소스 집약적입니다.
- 메모리 공유: 동일한 프로세스 내의 스레드는 메모리를 공유하지만 프로세스는 별도의 메모리 공간을 갖습니다.
- 통신: 스레드 간 통신은 프로세스 간 통신보다 간단하고 빠릅니다.
- 격리: 프로세스는 다른 프로세스와 메모리를 공유하지 않으므로 더 나은 격리와 보안을 제공합니다.
- 내결함성: 한 스레드의 충돌은 전체 프로세스에 영향을 미칠 수 있지만 한 프로세스의 충돌은 다른 프로세스에 직접 영향을 미치지 않습니다.
최신 운영 체제에서는 프로세스와 스레드가 모두 프로그램의 멀티태스킹 및 동시 실행에서 중요한 역할을 합니다. 프로세스와 스레드 중 선택은 격리 필요성, 리소스 사용, 프로그램의 여러 부분 간 통신 등 애플리케이션의 특정 요구 사항에 따라 달라집니다.
~ Java5 | Runnable, Thread |
---|---|
Java5 | Callable, Future, Executor, ExecutorService, Executors |
Java7 | Fork/Join, RecursiveTask |
Java8 | CompletableFuture |
Java9 | Flow |
1️⃣ ~ Java5: Thread, Runnable
Thread: 스레드 생성을 위해 Java에서 미리 구현해둔 클래스
Runnable: 스레드의 행위를 정의하는 함수형 인터페이스 (리턴타입X, 파라미터X)
Thread thread1 = new Thread(() -> System.out.println("Thread1: " + Thread.currentThread().getName()));
Thread thread2 = new Thread(() -> System.out.println("Thread2: " + Thread.currentThread().getName()));
thread1.start();
thread2.start();
단점
- Runnable 인터페이스의 스펙상, 값의 반환이 불가하여 관련된 처리에 제약이 있다.
- 스레드 생성을 직접하는 등 저수준 API로 인한 불편함
- 매번 쓰레드 생성과 종료하는 오버헤드가 발생
- 쓰레드들의 관리가 어려움
2️⃣ Java5: Callable, Future, Executor, ExecutorService, Executors
Callable: 스레드의 행위를 정의하는 함수형 인터페이스 (리턴타입O, 파라미터X)
@FunctionalInterface
public interface Callable<V> {
V call();
}
Future: 미래에 완료된 Callable의 반환값을 구하기 위해 사용되는 것. 비동기 작업을 갖고 있어 미래에 실행 결과를 얻도록 도와준다.
즉, 비동기 작업의 현재 상태를 확인 / 기다림 / 결과를 얻는 방법 등을 제공한다.
public interface Future<V> {
boolean isCancelled();
boolean isDone();
V get()
}
Process
-
플랫폼별 구현이 포함된 추상 클래스
-
입출력 관련 자원을 할당 받아 생성됨
- 몇몇 네이티브 플랫폼이 표준 입출력 스트림에 제한된 버퍼 크기만 허용하기 때문에, 입력 스트림을 쓰거나 출력 스트림을 읽을 때 일시적인 실패가 일어나면 하위 프로세스가 차단되거나 교착 상태에 빠질 수도 있다.
-
api
- getInputStream(), getOutputStream(), getErrorStream(), getInputStream(), getOutputStream(), getErrorStream()
- waitFor(), exitValue()waitFor(), exitValue()
- destroy(), destroyForcibly()
- isAlive()
ProcessBuilder
- Runtime.exec()에 비해 프로세스를 생성하는 보다 유연한 방법을 제공합니다..
- 프로세스를 시작하기 전에 프로세스 환경, 작업 디렉터리 및 I/O 리디렉션을 설정할 수 있습니다.
- 동일한 구성으로 여러 프로세스를 만들 수 있습니다.
- api
- command(): 프로세스에 대한 명령과 인수를 설정합니다.
- directory(): 프로세스의 작업 디렉토리를 설정합니다.
- environment(): 프로세스 환경 변수를 수정합니다.
- redirectInput(), redirectOutput(), redirectError(): I/O 리디렉션을 구성합니다.
- start(): 프로세스를 생성하고 시작하여 Process 인스턴스를 반환합니다.
ProcessHandle
- java 9부터 등장
- ProcessHandle은 네이티브 프로세스를 식별하고 제어합니다.
- 각 개별 프로세스의 활성 상태를 모니터링하고, 하위 프로세스를 나열하고, 프로세스에 대한 정보를 얻거나 프로세스를 삭제할 수 있습니다.
- 프로세스 인스턴스는 현재 프로세스에 의해 시작되었으며 프로세스 입력, 출력 및 오류 스트림에 대한 액세스를 추가로 제공합니다.
- 프로세스 상태에 대한 스냅샷을 제공합니다.
- ConcurrentMap 기반 프로세스 ID, 상위 프로세스 및 하위 프로세스에 대한 액세스를 제공합니다.
- api
- current(): 현재 프로세스의 핸들을 가져옵니다.
- of(long pid): 주어진 프로세스 ID에 대한 프로세스 핸들을 가져옵니다.
- children(): 하위 프로세스 핸들의 스트림을 반환합니다.
- parent(): 상위 프로세스 핸들을 반환합니다.
- info(): 명령, 시작 시간, CPU 사용량과 같은 프로세스 정보를 제공합니다.
- onExit(): 프로세스가 종료되면 완료되는 CompletableFuture를 반환합니다.