스택(stack) 은 메모리영역으로 지역 변수가 저장되고 기능이 실행되는 영역입니다. 그리고 명령어 포인터는 그냥 포인터 일뿐입니다.
스레드가 실행할 다음 명령어의 주소를 가리키느 역할을 한다. 왜 각각의 스레드가 자체 스택과 명령어 포인트를 가지는지 쉽게 이해하려면 각각의 스레드는 특정 순간에 서로 다른 함수를 이용해 다른 명령을 수행한다는것만 기억하자.
컨텍스 스위치
하나의 스레드 실행을 멈추고 다른 스레드를 스케줄링한 다음 다시 실행하는것이 컨텍스 스위치입니다.
동시에 많은 스레드를 다룰 때는 효율성이 떨어지기 때문입니다. 이것이 병행성을 위한 대가입니다.
우리가 생각을 가다듬고 집중력을 회복하는 시간과 똑같습니다. 집이나 직장에서 여러 일을 동시에 하면 생산성이 떨이지게 됩니다.
주변의 뱅하는 받는다거나 다른 일로 전환하는 순간에 말이죠~!
운영체제도 마찬가지 입니다.
CPU 에서 실행되는 각 스레드는 CPU 내의 레지스터나 캐시 메모리 내의 커널 리소스 같은 것을 일정 부분 차지하게 됩니다.
다른 스레드로 전화할 때는 기존의 모든 데이터를 저장하고 또 다른 스레드의 리소스를 CPU와 메모리에 복원해야 합니다.
컨텍스트 스위치에서 알아야한느것은 너무 많은 스레드를 가동하게 되면 'Trashing' 이 발생한다는겁니다.
이 말은 즉슨, 운영 체제가 우리가 시킨 일을 생산적으로 해내는 대신 스레드 관리 즉, 컨텍스트 스위치에 더 많은 시간을 할애한다는 거죠.
또, 스레드는 프로세스보다 리소스를 더 적게 사용합니다. 프로세스 내의 스레듣르은 공유하는 리소스가 많이 때문입니다.
즉, 같은 프로세스에 속한 두 스레드 간의 컨텍스트 스위치가 각각 다른 프로세스의 두 스레드 간의 컨텍스트 스위치보다 효율적인 겁니다.
컨텍스트 스위칭을 알았으니 운영체제가 어떤 스레드를 실행할지 언제 컨텍스트 스위치를 결정하는지 알아봅시다.
예시) 텍스트 편집기로 과제를 한다고 가정을 합니다.
좋아하는 음악을 들으면서 텍스트 편집기를 사용한다고 하면, 프로세스는 2개 입니다.
간단한 설명을 위해 음악 플레이어에 스레드 2개가 있다고 합니다.
하나는 파일에서 음악을 로딩해 스피커로 전송하는거고
하나는 UI 스레드로 트랙의 상황을 보여주고 재생, 멈춤 버튼의 마우스 클릭에 반응합니다.
텍스트 편집기도 스레드는 2개 입니다.
하나는 역시, UI 스레드로 우리가 입력한 걸 보여주며 키보드와 마우스 입력에 반응합니다.
다른 스레드는 현재 작업을 2초마다 파일에 저장하죠.
Arriaval Order | Length |
1 | file Saver |
2 | Music player |
3 | text editor UI |
4 | Music Player UI |
이렇게 하나의 코어에 스레드 4개가 되었고 이제 코어 하나로 스케줄을 짜야합니다.
작업의 도착순서와 실행시간이 주어진다고 가정한다면 운영체제는 누구를 가정 먼저 실행할까요?
먼저 도착하는 작업이 먼저 실행되는것이라고 가정하면
위에 1->2->3->4 순서입니다. 단 이 접근법의 문제점은 실행 시간이 긴 스레드가 먼저 도착하면 다른 스레드에 기아 현싱이 발생한다는 겁니다.
특히 UI 스레드에는 큰 문제입니다. 애플리케이션의 응답성을 방해해 최악의 사용자 경험을 야기할 테니까뇽
위에 표를 보듯이 UI 스레드는 보통 짧습니다. UI 스레드는 사용자의 입역을 단순히 화면에 띄우기만 하거든요.
그럼 짧은 순서대로 스케쥴을 짜면 어떻게 될까요??
아까와 전반대의 문제가 발생합니다.
사용자 관련 이벤트가 항상 시스템에 있는 겁니다.
가장 짧은 작업을 항상 맨 앞에 배치하게 되면 계산이 들어간 긴 작업들은 영원히 실행이 될수 없는겁니다.
이 짧은 모의 실험을 통해 우리가 알게 된것이 있습니다.
운영체제가 스레드에 CPU 시간을 공평하게 할당할 때 어떤 문제점이 생기는지 말이죠.
그럼 일반적인 운영체제에서는 어떻게 작동하는지 알아봅시다.
운영체제는 '에포크'에 맞춰 시간을 적당한 크기로 나눕니다.
그리고 스레드의 타임 슬라이스를 종류별로 에포크에 할당하죠.
하지만 모든 스레드가 각 에포크에서 실행되거나 완료되지는 않아요.
스레드에 실간을 할당하는 방법은 운영 체제가 각각의 스레드에 적용하는 동적 우선순위에 달렸습니다.
정적 우선순위는 개발자가 미리 설정하고 보너스는 운영체제가 각각의 메포크마다 조절합니다.
이렇게 하면 운영체제는 즉각적인 반은이 필요한 실시간 스레드나 인터랙티브 스레드에게 우선권을 주게 됩니다.
하지만 동시에 기아 현상을 막기 위해 이전 에포크에서 실행 시간이 부족했거나 완료되 않은 스레드도 놓지지 않습니다.
첫 번째 멀티 스레드 애플리케이션 작업을 시작하기 전에 마지막으로 확인할 것은 하나의 프로그램에 멀티스레드를 사용하는 시점과 새로 생성환 프로그램을 다른 프로세스에 실행하는 시점입니다.
어떤 방식을 쓸 것인지 마음속으로 결정해야 합니다. 멀티 스레드 접근법과 멀티 프로레스 접근법 중에서 말이죠 !!
스레드들은 많은 리소스를 공유합니다 그러니 많은 데이터를 공유하는 다양한 작업을 실행하려면 멀티 스레드 애플리케이션 아키텍처가 좋을겁니다 .뿐만 아니라 스레드는 생성과 파기가 훨씬 빠르고 같은 프로세스 안에서 멀티 스레드끼리 전환하는것이 여러 프로세스 사이에서 전환하는것보다 훨씬 빠릅니다.
하지만 독립된 프로그램을 독립된 프로세스에 실행하는 게 좋을 수도 있습니다.
가장 중요한 점이 보안과 안정성이라고 하면말이죠
여기서는 각각의 프로세스가 완전히 독립되어 있지만 멀티 스레드 애플리케이션에서는 앱 전체가 스레드 하나에 다운될 수도 있습니다.
또, 서로 관련이 없는 작업을 실행할 경우 같은 프로세스에 통합하는것도 아무 의미가 없다.
컨텍스트 스위치와 이것이 성능에 미치는 영향을 배웠습니다. 다음 시간에는 운영체제의 일반적인 스레드 스케중링 방법과 각 운영체제가 자체적인 스케줄링 알고리즘으로 움직인다는것도 배웠습니다.
멀티 스레드 애플리케이션 아키텍처와 멀티 프로레스 애플리케이션 아키텍처가 각각 어느 경우에 유용하게 사용될수 있는지도 알아봤습니다.
'lecture > Java 멀티스레딩, 병행성 및 성능 최적화' 카테고리의 다른 글
애플리케이션에서 여러 개의 스레드를 사용하는 이유? (0) | 2023.08.17 |
---|---|
lecture 2. 멀티 스레드 프로그램 구성 (0) | 2023.08.17 |