오늘날 운영체제는 여러 프로세스(Process)를 동시에 실행할 수 있다.
ex_유튜브로 노래를 들으며 동영상 편집을 할 수 있다.
프로세스도 한번에 여러가지 작업이 가능하다
ex_VScode에서 코드를 작성하면서 동시에 잘못된 문법을 체크해 붉은색으로 표시해준다.
프로세스는 실행 파일이 실행되어 메모리에 적재된 인스턴스.
예를 들어 워드가 실행 파일이라면, 이 실행 파일에 담겨 있는 데이터와 코드가 메모리에 적재되어 동작하는 것이 프로세스이다.
프로세스는 반드시 하나 이상의 스레드로 구성되는데, 스레드는 운영체제가 CPU시간을 할당하는 기본단위이다.
운영체제와 프로세스, 프로세스와 스레드
단일 스레드: "프로세스3"처럼 한 번에 한 가지 일만 하는 것
멀티 스레드: "프로세스1","프로세스2","프로세스3"처럼 여러 개의 스레드를 가져 다중 작업을 하는 것
이 프로그램에서 사용자와의 대화를 위한 스레드를 하나 더 추가한다면 파일 복사를 하면서도 사용자로부터 명령을 입력받을 수 있다.단일 스레드를 사용하는 프로그램을 만들었다.
이 프로그램에서 파일 복사만 30분이 걸린다.
사용자가 파일 복사를 취소하고 싶어도 프로그램은 사용자에게 반응하지 않아서 복사를 취소할 수가 없다.
결국 작업 관리자를 이용해서 강제로 프로세스를 종료시켜야했다.
멀티 프로세스 방식에 비해 멀티 스레드 방식이 자원 공유가 쉽다.
멀티 프로세스는 GUI가 없는 웹 서버 같은 서버용 애플리케이션에서 많이 취하는 구조이다.
프로세스끼리 데이터를 교환하려면 소켓이나 공유 메모리 같은 IPC(Inter Process Communication)를 이용해야하는데 이는 꽤나 번거롭다.
반면 멀티 스레드 방식에서는 그저 스레드끼리 코드 내의 변수를 같이 사용하는 것만으로도 데이터 교환을 할 수가 있다.
구현하기가 매우 까다롭다.
멀티 프로세스 기반의 소프트웨어는 여러 개의 자식 프로세스 중 하나에 문제가 생기면 그 자식 프로세스 하나가 kill되는 게 끝.
멀티 스레드 기반의 소프트웨어는 자식 스레드 중 하나에 문제가 생기면 전체 프로세스에 영향이 발생한다.
스레드를 너무 많이 사용하면 오히려 성능이 더 저하된다.
스레드가 CPU를 사용하기 위해서는 작업 간 전환(context swtiching)을 해야하는데, 이 작업이 비용을 많이 소모한다.
많은 스레드가 너무 자주 작업 간 전환을 수행하면 애플리케이션이 실제로 일하는 시간에 비해 작업 전환에 사용하는 시간이 커져 성능이 저하된다.
C#은 .NET에서 스레드를 제어하는 클래스 System.Threading.Thread를 제공한다.
//스레드가 실행할 메소드 static void DoSometing() { for(int i = 0 ; i < 5 ; i++){ Console.WriteLine("DoSomething : {0}",i); } } static void Main(string[] args){ //Thread인스턴스 생성 및 인수로 메서드를 넘긴다. Thread t1 = new Thread(new ThreadStart(DoSomething)); //스레드 시작 t1.Start(); //스레드의 종료 대기 t1.Join(); }
위 코드에서 생성한 스레드가 적재되는 시점은 인스턴스를 만드는 것이 아닌 t1.Start()이다.
생성한 스레드를 실행하면 메인 프로세스에서 나와 작업을 수행하고 Join()메소드가 반환되는 시점에서 다시 프로세스로 합류한다.
애플리케이션을 구성하는 각 스레드는 여러 가지 자원을 공유한다.
파일 핸들, 네트워크 커넥션, 메모리에 선언한 변수를 통해 공유를 한다.
동시에 여러 작업을 할 때는 멀티 스레드를 사용하는 것이 멀티 프로세스보다 시스템 자원(메모리)를 더 적게 사용한다.
스레드가 프로세스에 비해 탁월한 기능을 가지고 있어보이지만, 스레드에도 단점이 있다.
바로 동기화(Sysnchronize)이슈이다.
스레드1이 공유 자원 내의 어떤 데이터를 조작한다.
스레드2에게 제어권을 넘겨준 이후 스레드2가 그 데이터를 번경한다.
스레드1이 다시 제어권을 받아 남은 작업을 계속할 때 원하지 않는 결과가 나온다.
- 은행 출금 동기화 문제
이러한 문제를 해결하기 위해 특정 자원에 접근하지 못하도록 Lock을 걸어 동기화 문제를 해결한다.
다양한 동기화 기법을 운영체제가 제공한다.
하지만 스케줄링을 운영체제가 자동으로 해주지 않고, 프로그래머가 적절한 기법을 선택하여 직접 구현해야한다.
cf_스케줄링 기법
장점 : 응답성 향상, 자원공유 용이, 경제성
단점 : 동기화 이슈, 잦은 스위칭시 비용 증가
현재 진행하고 있는 Task(Process, Thread)의 상태를 저장하고 다음 진행할 Task의 상태 값을 읽어 적용하는 과정을 말합니다.
Context Switching 비용은 Process가 Thread보다 많이 듭니다.
Thread는 Stack 영역을 제외한 모든 메모리를 공유하기 때문에
Context Switching 발생시 Stack 영역만 변경을 진행하면 됩니다.