3 minute read

스터디 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) : 위와 비슷하지만, 명령어를 호출하는 쪽에서 예전 값과 새 값을 모두 제공함
      예전 값이 메모리 위치
  • 장기 락 구현
    보통 여러 프로그램이 자원에 접근하면 안되는 경우
    메모리보다 좀 더 영구적 저장소에 저장되어야 함 -> 파일 사용하여 구현
    ***
  • 브라우저 자바스크립트
    자바스크립트는 단일 스레드인데 동시성 문제가?
    원리 : 사용자 이벤트에 응하는 짧은 프로그램 실행용으로 만들어졌기 때문에 이벤트루프 모델 사용한다.
    실행할 작업을 이벤트 큐에 추가하고 하나씩 꺼내 실행하는 것
    (이때 프로그래머가 이벤트큐 추가되는 순서 제어 불가 - 마우스 버튼 클릭순서 제어 불가하듯이)

비동기 통신은 나중에 나왔는데 초기에는 고려되지 않았다.
응답에 대한 도착순서는 제어할 수 없기 때문에 이슈 발생!

순서를 지키려면 함수안에 함수를 넣어야 하는가?

  • 비동기 함수와 프로미스
    프로미스비동기 콜백 메커니즘 을 언어 고유 기능으로 넣어
    라이브러리가 비동기 연산의 구현을 제대로 하게 한다.

–> 다음주 프로미스 함수 공부할 예정


추가(프로그래밍 면접 이렇게 준비한다. 10장 동기성)

동기화는 보통 모니터와 세마포어를 써서 처리한다.
하지만 잘못쓰면 데드락 때문에 스레드가 멎어버릴 수 있으므로
멀티스레드 코드를 만드려면 상당한 노력과 주의 필요!

  • 스레드 동기화 : 스레드와 공유자원 사이의 상호작용 제어(상황에 따라 모니터와 세마포어 사용)

    • 모니터 : 상호배제 자물쇠로 보호되는 루틴의 집합 (-> 자물쇠 획득과 해제 모두 자동처리)
      스레드는 자물쇠 획득 전 까지 모니터에 속하는 루틴 하나도 실행 불가,
      한 모니터 내에서는 한 스레드씩 실행됨,
      대기를 위한 스레드가 스스로 멈추면 모니터로 진입할 수 있고,
      실행중인 스레드가 자물쇠 놓아주면 대기 중인 스레드가 다시 깨어나서 자물쇠 재획득하게 됨

    • 세마포어 : 공유자원을 보호하기 위한 자물쇠만 존재 (-> 자물쇠 해제 작업 일일히 처리해줘야 함)
      (기본적인 상호배제 세마포어(=뮤텍스), 카운팅 세마포어, 이벤트 세마포어 등이 있음)

    • 대부분의 시스템에서 일정시간 안에 획득하지 못하면 타임아웃 하는 방법도 제공
    • 스레드 동기화에는 공유자원 접근, 자물쇠 획득과 해제하는데 걸리는 시간이라는 비용이 존재
    • 때문에 자바에서는 문자열 처리에 스레드용(StringBuffer), 비스레드용(StringBuilder, 더빠름) 구분하기도 함
    • 스레딩 예제 : synchronized 구문 사용해서 잠근다.