현재까지는 흐름(쓰레드가)이 하나뿐인 프로세스를 생각해 왔다.
그러나, 하나의 프로세스는 여러개의 쓰레드들을 컨트롤 할 수 있다.
•
프로세스가 한번에 여러개 동작 할 수 있었던 이유?
cpu가 program counter를 가지고 있고, 이를 context switching 할시에 바꿔주면 , 각각의 실횅할 프로세스의 context를 가지고 와서 실행 할 수 있다.
→이 때, 이 pc(program counter)즉, register set 정보만 별도로 유지 한다면, 하나의 프로그램(프로세스 안에서) 굳이 fork할 필요 없이, 실행 쓰레드만 달리 할 수 있다.
•
쓰레드란?
◦
a lightweight process (LWP)
◦
멀티 쓰레딩이 제공 될 때, 실제로 “CPU를 점유하는 기본 단위”이다
◦
어떤 프로세스 안에 여러개의 쓰레드가 있다고 하면, 이 프로세스의 ID(PID)가 CPU를 점유하는 것이 아니라, 이 프로세스 내의 쓰레드 ID(TID)가 CPU를 점유한다.
◦
TID 별로 program counter, register set, stack이 달라진다.
◦
code / data / files 메모리 영역은 한프로세스 내의 쓰레드 들이 공유 한다.
•
멀티 쓰레드 하면 뭐가 좋을까?
◦
서버 프로세스가 클라이언트 프로세스와 소켓 등으로 통신을 하는 경우, 그리고 그 통신이 blocking 방식이라면, client에게서 요청된 정보를 다 응답 할 때까지 서버프로세스는 그 다음 작업을 할 수 없다. 이때 client의 요청을 받는 순간 쓰레드를 만들어 응답 하게 하고 다른 쓰레드에서 서버 프로세스가 하는 다른 일을 실행 하게 할 수 있다.
◦
대표적인 클라이언트-서버 시스템인 웹서버, 대부분의 현대적인 애플리케이션을 멀티 쓰레드를 지원한다.
•
멀티쓰레드의 장점 4가지
◦
Responsiveness(응답에 이점이 있다) : 유저인터페이스 등을 처리 할 때 프로세스가 blocking 되어있을 필요가 없다.
◦
Resource Sharing(자원 공유) : 프로세스간 IPC를 할 때 shared memory를 사용을 하거나, O/S에게 요청을 보내(message passing) message Queue를 이용했었다. 쓰레드들은 code와 data메모리 영역를 공유하기 때문에, 쓰레드는 따로 shwared memory를 할당할 필요없이 데이터를 공유할 수 있다.
◦
Economy (경제성도 좋다): 프로세스 생성(fork등)보다 훨씬 비용이 저렴하다.(code, data단의 중복되는 메모리를 복사하지 않아도 된다.) 또 문맥교환시, PCB 교환보다 쓰레드 변경이 더 비용이 저렴하다.
◦
Scalability (확장성이 좋다): 멀티 쓰레드를 가진 프로세스는 멀티프로세서 아키텍처를 사용할 수 있다. 병렬 처리도 가능해 진다.
⇒ 멀티 쓰레드를 배우기 위해 멀티 프로세스를 배웠다고 해도 과언이 아니다!
자바는 언어및 자바 가상머신을 디자인 할 때 부터 쓰레드 모델을 도입해서, 쓰레드 기반으로 개발을 했다. API도 매우 쉽게 사용할 수 있게 되어있다. → 쓰레드의 생성 및 관리가 매우 용이 하다.
•
자바에서 쓰레드를 사용하는 방법 3가지
◦
쓰레드라는 클래스를 상속 받는다. (권장 x)
▪
“Thread” 클래스를 상속한 새 클래스를 만든다.
▪
public void run() 메서드를 오버라이드 한다.
⇒ 문제점 : 자바에서는 다중상속을 지원하지 않기 때문에, 쓰레드를 상속 받고 나면 다른 걸 상속 받을 수가 없다.
.run으로 바로 호출하는 것이 아니라, .start를 호출하고, 이 메서드가 .run을 호출 하는 방식으로 사용한다.
<실행 결과>
◦
Implementing the Runnable interface (권장) ⇒ 가장 많이 쓰는 방법!
▪
Runnable 인터페이스를 구현한 새로운 클래스를 정의하고
▪
public void run() 메서드를 오버라이드 한다.
▪
구현한 새로운 클래스를 Thread class의 생성자의 파라미터로 넘겨주면 쓰레드가 생성 된다.
◦
익명 쓰레드 이용(Using the Lamda expression) →좀더 간편
▪
새로운 클래스를 선언하지 않고,
▪
람다 익스프레션으로 Runnable interface를 선언하자.
자바 1.8부터 함수형 프로그래밍을 지원하므로, 그 이상 버전에서부터 사용 가능. 실행결과는 위와 동일하다.
•
프로세스는 wait!
쓰레드는 join!
•
쓰레드의 종료는 interrupt!(stop을 사용하면 동기화 문제가 발생함)
◦
쓰레드 역시 프로세스의 status를 그대로 가지고 있다(ex> new, waiting, running …)
◦
인터럽트를 걸어주면 exit로 빠져 나간다.
멀티코어 시스템에서는 멀티쓰레딩이 조금 더 복잡해졌다.
•
concurrency는 훨씬 향상되었다.
•
single-core : 쓰레드들이 시간의 흐름에 따라 interleaved 하게 실행된다.(시분할)
•
multiple-cores : 쓰레드들이 parallel하게 실행된다.
타임 쉐어링(시분할)과 동시에 parallel하게 실행된다.
멀티코어 시스템, 멀티 쓰레딩 프로그램에서 프로그래머가 할 일
•
Identifying tasks : 어떤 task들이 separate 될 수 있는지를 잘 분별해야한다. ex> 정수들의 합을 구하는 문제 / 병합 정렬 등등
•
Balance : balance도 맞춰줘야한다. 각 쓰레드가 비슷한 시간이 걸리는 양의 task를 할 수 있도록.
•
Data splitting : 데이터들을 어떻게 나눌지
•
Data dependency : 데이터들의 의존성 처리 → 동기화 관련 문제
•
Testing and debugging : 싱글 스레딩 보다 굉장히 어려워 진다.
병렬처리의 가능성 두가지
데이터 병렬성 : 데이터를 각각의 코어에 쪼개 준다.
데스크 병렬성 : 데이터는 그대로 두고 테스크를 쪼개 준다.
⇒ 현재는 이를 따질 필요가 전혀 없다.
훨씬 수준 높은 “distruituted”(분산) 시스템 이 나왔기 때문.
→ Haddop(하둡) 과 같은 것들로, 컴퓨팅 자원도 순환되고, 한개의 컴퓨터가 아닌, map reduce등의 분산 시스템을 사용하게 되었다 (⇒ 분산 시스템을 공부하면 알게 됨)
Amdahl’s Law(암달의 법칙)
•
CPU 코어는 무조건 많을 수록 좋은가?
S ⇒ 어떤 시스템에서 시리얼하게만 실행될 수 있는 비율을 말한다.(병렬처리가 불가한 작업)
N⇒ 코어의 갯수
코어가 4배라면 이론적으론 속도도 4배 빨라져야 겠지만, 모두가 병렬 처리할 수 있는 작업은 아니기 때문에, 이에 못 미친다.