# 서울숲_D_Day14 리뷰 레포트
## 참석자
신용호, 여재환, 이영훈, 이정민
## 1. 코드 동작 이해
### main
- 바리스타의 수, 주문량, 주문 완료 출력 등 DOM Control 처리
- appendChild()나 innerHTML로 해당 element안에 추가할 수 있다.
- 각 커피에 대한 작업시간 설정
- manager worker를 호출하고 바리스타 수, 주문량을 전달
### manager
- 할 일들을 main에서 받음
- 할 일들과 워커들을 각각 배열에 저장
- 배열에서 한 개의 요소를 제거하면서 barista 워커에게 일을 부여
- barista 워커가 일이 끝나면 배열이 비었는지 확인하고 비어있지 않으면 그 일을 부여
- 마지막 워커가 일을 끝내면 main으로 모든 일이 끝났다는 정보 전달
### barista
- timer (setTimeout(), while 문으로 동기 sleep 구현)
- 매니저로부터 할당받은 task들을 수행
- 할당받은 작업이 끝나면 매니저에게 작업완료를 알림
## 2. 코드 동작 개선
### 신용호
- 전역 변수 수 감소시키기
- 문자열로 함수 간 상호작용을 줄이기
- 각각의 워커에게 일을 부여할 때 비동기적으로 해보기
### 여재환
- 쓰레드 풀의 개념적 이해가 필요
- pre 태그 대신 innerHTML, appendchild와 같은 메서드의 활용으로 코드를 깔끔하게 만들 필요가 있다.
- 멀티쓰레딩을 위해 재귀적으로 동작하는 부분을 이벤트처리의 방식으로 변경하면 보다 멀티쓰레딩스러운 코드가 될 수 있다.
### 이영훈
- 모듈화 필요
- async/await/promise 등 asynchronous와 setTimeout/setInterval 등 timer 정리 필요
- Call Stack과 Task Queue/MicroTask Queue/Job Queue등의 EventLoop의 동작방식 정리 필요
- 처음에 무한반복문을 통해서 하려고 했음
### 이정민
- `setTimeout(() => {}, 0)`의 무분별한 사용 자제
- if 조건문 다시 확인하기
- 재귀로 호출하는 것과 postMessage, onmessage의 상호호출로 구현하는 것의 차이 공부
## 3. Consideration
### 스스로 확인할 사항
#### 멀티 스레드 스케줄링 방식에 대해 학습한다.
자바와 같은 언어는 **멀티 스레드**를 지원한다. `main()` 함수가 작업 스레드를 병렬적으로 생성해 한 번에 여러 일을 해결할 수 있게 한다. 스레드의 개수가 코어의 수 보다 많을 경우, **스레드를 어떤 순서에 의해 동시성으로 실행할 것인가**를 결정해야 하는데, 이것을 **스레드 스케줄링**이라고 한다.
- 선점형 스레드 스케줄링(preemptive)
- 우선순위: 우선순위에 따라 할당. proirity 값이 높은 스레드가 실행 상태를 더 많이 가짐.
- 라운드로빈: 시간 할당량(Time Slice)를 정해서 하나의 스레드를 정해진 시간만큼 실행시키고 다시 다른 스레드를 실행함
- 비선점형 스레드 스케줄링(non preemptive)
- 실행중인 스레드가 다음 스레드에게 할당권을 넘길 때까지 기다리는 방식.
- FIFO(FCFS): 먼저 들어온 작업부터 처리
참고:
* https://sjh836.tistory.com/121
* [[OS] 스케줄링 알고리즘](https://k39335.tistory.com/33)
#### 스레드 동작 방식과 바리스타 작업 방식에 대해 비교한다.
- 스레드와 바리스타는 모두 프로세스(커피주문)에 대한 일을 수행한다는 점에서 같은 역할을 수행한다. 기본적으로 작업관리자로부터 수행해야하는 태스크를 할당 받고, 할당받은 작업이 종료후에 관리자에게 알리고 다음 태스크를 위해 대기하는 점이 동일하다.
- 쓰레드는 기본적으로 쓰레드 그룹에 포함되게 되는데 그러한 부분에 대한 구현이 불포함되어있다.
- thread에서는 ready/running/block의 단계로 나뉘어 처리된다. 하지만, 바리스타에서는 단계로 나뉘지는 않는다.
#### Web Worker(또는 Worker Thread)에서 사용하지 않은 기능에 대해 학습한다.
- `this.messageerror`
- 특정 Worker에게 에러를 전달하여 `onmessageerror`를 실행시키게 함
- `this.onmessageerror`
- `onmessage`와 비슷하게 에러가 전달되면 특정 함수 호출
- `this.terminate()`
- 워커를 바로 종료
- this
- context를 의미
- self
- window를 의미
#### setTimeout 내부 동작 방식에 대해 학습한다.
- 비록 Javascript는 단일 스레드 언어이지만 브라우저에는 Javascript 엔진 스레드, UI 스레드, 타이밍 스레드로 최소 3개의 스레드가 존재
- `setTimeout()`은 타이밍 스레드에서 처리됨
- 타이밍 스레드에서 처리가 되면 이벤트 큐로 콜백함수가 넘어가고, 스택이 다 없어진 후에 실행됨
##### [ref](https://stackoverflow.com/questions/22051209/how-does-setinterval-and-settimeout-work)
### 다같이 확인할 사항
#### setTimeout 이외에 timer를 구현하기 위한 여러 방식에 대해 학습한다.
* **setInterval()**
* callback함수를 주기적으로 실행
* 따라서 반환값으로 받는 ID를clearInterval()의 매개변수에 넣는 종료부분을 넣어주어야한다.
* **setImmediate()**
* 현재 이벤트 루프 주기 끝에 코드를 실행. 현재 이벤트 루프의 모든 I/O 작업 후 다음 이벤트 루프에 스케줄링 된 모든 타이머 이전에 실행됩니다. 이 코드 실행은 setImmediate() 함수 호출 뒤에 오는 모든 코드는 setImmediate() 함수 인자 이전에 실행된다는 의미로 "바로 다음에" 실행한다고 생각할 수 있습니다.
* **requestAnimationFrame()**
* [**process.nextTick()**](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/)
* [**alarms()**](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms)
[ref](https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Code_snippets/Timers)
#### 멀티 스레드가 공용 리소스에 접근할 때 임계구역을 다루는 방식에 대해 학습한다. (Semaphore, Mutex 등)
- Process는 program의 단위로 각각 독립된 메모리 영역(Code,Data,Heap,Stack)을 가진다.
- Thread는 하나의 Process내에서 독립적인 task의 단위로 Process 내 메모리 영역(Code,Data,Heap,Stack) 중 Stack 영역에 만들어진다.
- 따라서, 나머지 Thread들과 Code,Data,Heap영역을 공유한다. 이로 인해 공유되는 영역 중 서로에게 영향을 끼치는 구역을 critical section이라고 부르며 이에 따라 서로 경쟁하는 상태인 race condition이 발생한다.
- 이를 해결하기 위해, 고안된 기법이 Semaphore, Mutex, Monitor 등이다.
#### Mutex(Mutual Exclusion)
- 일종의 Locking 매커니즘이다. lock을 가지고 있을 경우에만 공유 데이터에 접근 가능하다.
- 일부 음식점들은 공용 화장실 관리 차원에서 화장실을 잠궈두고(Locking) 다닌다. 손님들이 화장실에 가려면 주인에게 열쇠를 받은 후 가야한다. 물론 다음 손님이 화장실에 가려면 앞 손님이 열쇠를 반납해야 갈 수 있다. 이렇게 열쇠가 있는-lock을 가지고 있는 경우-에만 공유자원(화장실)에 접근할 수 있다. 이게 바로 Mutex라고 보면 된다. 유의할 점은 Lock에 대한 소유권이 있다는 점이다. 열쇠를 획득한 사람만 반납할 수 있다.
#### Semaphore
- 세마포어는 동시에 리소스에 접근할 수 있는 '허용 가능한 Counter의 갯수'를 가지고 있는 Counter로 보면 된다.
- 예를 들면 107호 병실에 방문객용 의자가 5개 있다고 치자. 간호사는 이 병실에 방문자가 5명만 들어갈 수 있도록 허용하고 나머지 방문객들은 밖에서 대기하도록 한다. Counter 갯수만큼 공유자원(병실)에 접근할 수 있다. 이 세마포어 Counter의 갯수에 따라 1개의 경우 Binary Semaphore, 2개 이상의 경우 Counting Semaphore라고 불린다. Binary Semaphore의 경우 개념적으로 Mutex와 같다고 볼 수 있다.
#### Monitor
- Mutex(Lock)와 Condition Variables(Queue라고도 함)을 가지고 있는 Synchronization 메카니즘이다.
- 예를 들어 자바에서 모든 객체는 Object 클래스를 상속 받는다. 이 Object 클래스에는 wait(), notifyAll(), notify() 메소드를 가지고 있는데 이게 바로 Condition Variables 역할이라고 보면 된다. 고로 모든 자바 객체는 Monitor를 가지고 있다. 자바에서는 Mutual Exclusion 해결을 위한 구현체로 Synchronized 키워드가 있다. 예를 들어 Synchronized가 메소드에 선언되어있고, 쓰레드A가 이미 Lock을 획득해서 Critical Section(메소드)을 수행중이라고 가정하자. 쓰레드B가 동일한 메소드를 수행하기 위해 해당 Object의 Lock을 획득해야 할 것이다. 이 Lock이 반환될 때까지 대기를 해야하는데 그 때 사용되는게 바로 Monitor다. 쓰레드A가 Lock을 반환하면 쓰레드B는 기다렸다가 Lock을 획득하게 된다. 그리고 Critical Section인 메소드를 수행할 수 있게 된다. 물론 Synchronized 키워드를 사용했을 때 자동적으로 수행되는 내부 동작이고, 별도로 명시적인 Monitor를 구현할 수도 있다.(이건 길어질거 같으니 별도 포스팅으로….) 아무튼 Monitor는 이렇게 Mutex(Lock)과 Condition Variables을 이용해서 Mutual Exclustion을 해결하고 있다. 그 외 Monitor의 다른 정의로는 공유자원에 안전하게 접근하기 위해 Mutual Exclusion가 랩핑된 Thread-Safe한 클래스, 객체, 모듈들을 의미하기도 한다.
[ref](https://jwprogramming.tistory.com/13)
#### 멀티 스레드 작업을 그룹으로 묶어서 동기화하는 방식에 대해 학습한다.
- java내에 ThreadGorup을 제공하는 것과 같다. (참고: [ref](https://www.javatpoint.com/threadgroup-in-java))
참고:
[스레드 그룹, 스레드 풀](https://m.blog.naver.com/PostView.nhn?blogId=qkrghdud0&logNo=220693345433&proxyReferer=https%3A%2F%2Fwww.google.com%2F)
[Process Control Block](https://en.wikipedia.org/wiki/Process_control_block)
[Thread](https://en.wikipedia.org/wiki/Thread_(computing))
[Scheduling](https://en.wikipedia.org/wiki/Scheduling_(computing))
[Process and Control Block workflow](https://www.d.umn.edu/~gshute/os/processes-and-threads.xhtml)
[Thread Pool](https://en.wikipedia.org/wiki/Thread_pool)
[Web Wokrer](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers)
[Timers](https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Code_snippets/Timers)
[alarms](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms)
[process.nextTick()](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/)
[process&thread](https://www.d.umn.edu/~gshute/os/processes-and-threads.xhtml)