스터디 1회차
스터디 1회차(한권으로 읽는 컴퓨터 구조와 프로그래밍)
12장 병렬성과 비동기성
컴퓨터는 어떻게 한번에 많은 일을 하는가(멀티태스킹에서 발생할 수 있는 문제점을 다룬다.)
-
경합조건 : 2개 이상의 프로그램이 같은 자원에 동시접근해서(공유) 자원사용 순서에 따라 결과가 달라지는 경우
-> 공유자원이 사용 중인지를 표현할 방법이 필요 - 프로세스와 스레드
- 프로세스 : 사용자 공간에서 실행되는 프로그램
- 스레드 : 정적인 데이터와 힙 공유하지만, 자체적으로 스택을 갖는 프로그램의 일부
스레드는 자신이 CPU 레지스터 완전히 소유한다고 가정 -> 스레드 스케줄러가 CPU 레지스터 저장해야 함
스레드는 일반 프로세스보다 저장할 컨택스트 크기가 훨씬 작아 문맥전환이 더 빠름 -> 경량프로세스라고 부름
스레드는 데이터를 공유함
생기는 문제 :
1) 보안문제
2) 한 탭에서 문제 생기면 전체가 멈추거나 다른탭이 작업내용 잃어버릴 수 있음 ***
-
락(상호배제를 위한)
락의 위치가 중요한 이유?
락을 지킬지 안지킬지는 프로그램이 정함, 락은 그저 조언을 해주는 어드바이저리일 뿐
잠그는시간 최소화, 잠그는 작업영역 크기 최소화 권장 - 락 대기
락을 기다리는 동안 하는 일
- 바쁜대기(스핀(회전/뺑뺑이)) : 락을 성공적으로 얻을 때까지 획득을 반복시도(불필요한 전력소모)
-> 등록/ 통지 받는 방법
-> 모니터나 세마포어 써서 피할 수 있음
(참고로 이더넷은 락은 아니지만 충돌시 임의의 시간 기다린 다음 재시도 하게 됨) - 락요청방법
(1) 블로킹 : 시스템이 락 할당할 수 있을 때 까지 요청한 프로그램 일시중단시킴
(2) 논블로킹 : 프로그램 계속 실행되고 나중에 락을 얻었는지 여부를 통지받게 됨
***
- 바쁜대기(스핀(회전/뺑뺑이)) : 락을 성공적으로 얻을 때까지 획득을 반복시도(불필요한 전력소모)
-> 등록/ 통지 받는 방법
-> 모니터나 세마포어 써서 피할 수 있음
-
- 교착상태(데드락)
- 공유자원에서 원하는 것을 서로 가지고 있어서 더이상 진행되지 못하는 것
교착상태는 네가지 조건 모두 만족하는 경우에 발생(1) 상호배제 : 공유자원 함께 쓸 수 없어서 한 프로세스가 독점 사용해야 함 (2) 점유대기 : 프로세스들은 어드자원을 저유한 상태에서 다른 자원을 요청함 (3) 비선점 : 할당받은 자원 강제 뺏기 불가 (4) 순한대기 : 서로 순환적으로 다른 프로세스가 갖고 있는 자원 요구
해소방법(상황에 따라 이 중 하나를 사용한다.)
(1) 자원을 상호배제하지 않고 언제든 공유 가능하게 만든다.
(2) 어느 자원 점유 후 다른 자우너 요구하지 않고 한꺼번에 자원요구한다.
(3) 선점형으로 바꾼다.
(4) 자원마다 우선순위 부여 후 모든 프로세스가 정해진 순서대로만 자원을 요구한다.
- 단기 락 구현
- 검사 후 설정(test and set) 명령어 : 어떤 메모리 위치에 들어있는 값 1로 설정 후, 원래 그 위치에 있는 값 돌려줌
처음에는 0 있어야 함 - 비교 후 바꾸기(compare and swap) : 위와 비슷하지만, 명령어를 호출하는 쪽에서 예전 값과 새 값을 모두 제공함
예전 값이 메모리 위치
- 검사 후 설정(test and set) 명령어 : 어떤 메모리 위치에 들어있는 값 1로 설정 후, 원래 그 위치에 있는 값 돌려줌
- 장기 락 구현
보통 여러 프로그램이 자원에 접근하면 안되는 경우
메모리보다 좀 더 영구적 저장소에 저장되어야 함 -> 파일 사용하여 구현
*** - 브라우저 자바스크립트
자바스크립트는 단일 스레드인데 동시성 문제가?
원리 : 사용자 이벤트에 응하는 짧은 프로그램 실행용으로 만들어졌기 때문에 이벤트루프 모델 사용한다.
실행할 작업을 이벤트 큐에 추가하고 하나씩 꺼내 실행하는 것
(이때 프로그래머가 이벤트큐 추가되는 순서 제어 불가 - 마우스 버튼 클릭순서 제어 불가하듯이)
비동기 통신은 나중에 나왔는데 초기에는 고려되지 않았다.
응답에 대한 도착순서는 제어할 수 없기 때문에 이슈 발생!
순서를 지키려면 함수안에 함수를 넣어야 하는가?
- 비동기 함수와 프로미스
프로미스는 비동기 콜백 메커니즘 을 언어 고유 기능으로 넣어
라이브러리가 비동기 연산의 구현을 제대로 하게 한다.
–> 다음주 프로미스 함수 공부할 예정
추가(프로그래밍 면접 이렇게 준비한다. 10장 동기성)
동기화는 보통 모니터와 세마포어를 써서 처리한다.
하지만 잘못쓰면 데드락 때문에 스레드가 멎어버릴 수 있으므로
멀티스레드 코드를 만드려면 상당한 노력과 주의 필요!
-
스레드 동기화 : 스레드와 공유자원 사이의 상호작용 제어(상황에 따라 모니터와 세마포어 사용)
-
모니터 : 상호배제 자물쇠로 보호되는 루틴의 집합 (-> 자물쇠 획득과 해제 모두 자동처리)
스레드는 자물쇠 획득 전 까지 모니터에 속하는 루틴 하나도 실행 불가,
한 모니터 내에서는 한 스레드씩 실행됨,
대기를 위한 스레드가 스스로 멈추면 모니터로 진입할 수 있고,
실행중인 스레드가 자물쇠 놓아주면 대기 중인 스레드가 다시 깨어나서 자물쇠 재획득하게 됨 -
세마포어 : 공유자원을 보호하기 위한 자물쇠만 존재 (-> 자물쇠 해제 작업 일일히 처리해줘야 함)
(기본적인 상호배제 세마포어(=뮤텍스), 카운팅 세마포어, 이벤트 세마포어 등이 있음) - 대부분의 시스템에서 일정시간 안에 획득하지 못하면 타임아웃 하는 방법도 제공
- 스레드 동기화에는 공유자원 접근, 자물쇠 획득과 해제하는데 걸리는 시간이라는 비용이 존재
- 때문에 자바에서는 문자열 처리에 스레드용(StringBuffer), 비스레드용(StringBuilder, 더빠름) 구분하기도 함
- 스레딩 예제 : synchronized 구문 사용해서 잠근다.
-