SlideShare una empresa de Scribd logo
1 de 35
Descargar para leer sin conexión
3.4 Concurrency:
Time Is of the Essence
     병행성 : 시간은 중요하다




                    http://ohyecloudy.com
      http://cafe.naver.com/architect1.cafe
                                   2009.3.14
덮어쓰기 연산

(withdraw 25)   • 물체에 상태를 부여
75              • 계산 방법에 시갂 개념 추가
(withdraw 25)
50              • 만약 없다면 시갂의 영향을
                  받지 않고 한결같아 진다.
병행 시스템에서 시간의 본질
          (define (withdraw amount)
            (if (>= balance amount)
                (begin (set! balance (- balance amount))
                       balance)
                "Insufficient funds"))


                             100
  잔액 조회 : 100                                   잔액 조회 : 100

새 값 : 100 – 10 = 90
                                             새 값 : 100 – 25 = 75
 잔액을 90으로 set!                90
                                               잔액을 75로 set!
                              75
병행 프로그램의 올바른 동작
• 변수 하나에 여러 프로세스가 값을 덮어쓰
  려고 하는게 문제를 복잡하게 하고 있다.
• 상태 변화가 병행으로 일어날 때 예측 가
  능하게 동작하도록 병행 처리에 제약을 준
  다.
병행 처리에 제약을 주는 방법
• 상태 변수 하나를 같이 사용
  – 값을 바꿀 수 있는 연산 두 개가 동시에 돌아가지
    못하게 제약
• 차례대로 돌아가게 만들어 병행 프로그램과
  같은 결과를 만들어 낸다.
  – 어떤 차례인지 결정하지 않으면 올바른 결과가 여
    러 개다.
• 열의 퍼짐 시뮬레이션(flow of heat in an object)
  – 여러 개의 프로세스
  – 자기 값과 이웃 값의 평균으로 자기 값 수정
  – 되풀이 하다보면 올바른 값으로 수렴
병행 프로세스를 다루기 어려운 까닭

• 여러 프로세스에서 일어나는 사건의 차례
  가 서로 뒤엉킬 수 있기 때문
• 모든 경우를 하나하나 따져봐야 한다.
• 사건이 많아질수록 경우의 수가 폭발적으
  로 증가한다.
 – (a,b,c,d,e,f) 사건이 차례대로 일어나는 A 프로
   세스와 (x,y,z,w) 사건이 차례대로 일어나는 B
   프로세스가 있다면???
parallel-execute
        (define x 10)

        (parallel-execute (lambda () (set! x (* x x))) ; P1
                          (lambda () (set! x (+ x 1)))) ; P2

P1 : a (첫 번째 x 읽기), b (두 번째 x 읽기), c   (x를 덮어쓰기)

P2 : ㄱ (x 읽기), ㄴ (x를 덮어쓰기)
    두 프로세스가 끝난 다음 나올 수 있는 x의 값
        101 : a  b  c  ㄱ  ㄴ
        121 : ㄱ  ㄴ  a  b  c
        110 : a  ㄱ  ㄴ  b  c
         11 : ㄱ  a  b  c  ㄴ
        100 : a  b  ㄱ  ㄴ  c
병행성을 다스리는 방법
• 서로 뒤엉켜 돌아가는 여러 프로세스에 어
  떤 제약을 걸어서, 프로그램이 제대로 돌
  아갂다고 믿을 수 있도록 병행 시스템을
  설계하는 방법이 필요하다.
• 줄 세우개(serializer)가 한가지 방법.
줄 세우개(serializer)
• 병행으로 돌아가지 못하는 프로시저를 정
  의
• 여러 프로세스가 함께 쓰는 변수를 다스릴
  수 있다.
make-serializer
    (define x 10)
    (define s (make-serializer))
    (parallel-execute (s (lambda () (set! x (* x x)))) ; P1
                      (s (lambda () (set! x (+ x 1))))) ; P2

P1 : a (첫 번째 x 읽기), b (두 번째 x 읽기), c   (x를 덮어쓰기)

P2 : ㄱ (x 읽기), ㄴ (x를 덮어쓰기)
    두 프로세스가 끝난 다음 나올 수 있는 x의 값
        101 : a  b  c  ㄱ  ㄴ
        121 : ㄱ  ㄴ  a  b  c
        110 : a  ㄱ  ㄴ  b  c
         11 : ㄱ  a  b  c  ㄴ
        100 : a  b  ㄱ  ㄴ  c
줄 세우개를 사용한 은행 계정
• 잒액을 변경하는 withdraw, deposit 프로
  시저를 같은 줄 세우개를 사용해 동시에
  실행할 수 없게 제한했다.
• 줄 세우개는 계정마다 하나씩 가진다.
 – 서로 다른 계정의 작업은 병행으로 이루어진
   다.
(define (make-account balance)
  (define (withdraw amount)
    (if (>= balance amount)
        (begin (set! balance (- balance amount))
                balance)
        "Insufficient funds"))
  (define (deposit amount)
    (set! balance (+ balance amount))
    balance)
  (let ((protected (make-serializer)))
    (define (dispatch m)
      (cond ((eq? m 'withdraw) (protected withdraw))
             ((eq? m 'deposit) (protected deposit))
             ((eq? m 'balance) balance)
             (else (error "Unknown request -- MAKE-ACCOUNT" m))))
    dispatch))
연습 3.41
balance에 손을 댈 때 줄 세우기를 하지 않으면 제대로 돌아가지 않을
수도 있다는데 동의?
  (define (make-account balance)
    (define (withdraw amount)
      (if (>= balance amount)
          (begin (set! balance (- balance amount))
                  balance)
          "Insufficient funds"))
    (define (deposit amount)
      (set! balance (+ balance amount))
      balance)
    (let ((protected (make-serializer)))
      (define (dispatch m)
        (cond ((eq? m 'withdraw) (protected withdraw))
               ((eq? m 'deposit) (protected deposit))
             ((eq? m 'balance)
               ((protected (lambda () balance)))) ; serialized
              (else (error "Unknown request -- MAKE-ACCOUNT" m))))
      dispatch))
연습 3.41 풀이
• 줄 세우기를 한 결과 withdraw, deposit과
  balance는 동시에 실행되지 않는다.
• balance는 값을 변경하는 동작이 아니라
  값을 읽는 동작을 하는 프로시저.
• Ben은 balance를 거래 후 잒액으로 생각.
• 동의하지 않음.
• balance 프로시저를 실행하는 그 시갂에
  잒액을 보여줘야 한다고 생각한다.
연습 3.42
이렇게 만들어도 괜찮은가? 변경 젂 make-account와 병행성에 어떤
차이가 나는가?
 (define (make-account balance)
   (define (withdraw amount)
     (if (>= balance amount)
         (begin (set! balance (- balance amount))
                balance)
         "Insufficient funds"))
   (define (deposit amount)
     (set! balance (+ balance amount))
     balance)
   (let ((protected (make-serializer)))
     (let ((protected-withdraw (protected withdraw))
           (protected-deposit (protected deposit)))
      (define (dispatch m)
        (cond ((eq? m 'withdraw) protected-withdraw)
              ((eq? m 'deposit) protected-deposit)
              ((eq? m 'balance) balance)
              (else (error "Unknown request -- MAKE-ACCOUNT" m))))
      dispatch)))
연습 3.42 풀이
• 상관 없다.
• 이젂과 상관없이 make-serializer는 은행 계정
  하나당 하나가 존재한다.
• make-serializer 프로시저를 실행하는 프로시
  저를 미리 만들어서 같은 프로시저를 내놓는
  다고 하더라도 줄 세운 프로시저가 같이 쓰는
  뮤텍스와 같은 동기화 수단에 의존하기 때문
• 그렇기 때문에 병행성 또한 차이가 없다.
• 뒤에 make-serializer 구현 참조.
여러 자원을 함께 쓰는 문제
• 이제 까지 자원 하나를 여럾이 쓰는 예제.
 – 폴과 피터가 같이 쓰는 생활비 은행 계좌
• 여러 자원을 함께 쓰는 경우를 살펴보자.
 – 두 은행 계정의 남은 돈을 맞바꾸는 일.
exchange
     (define (exchange account1 account2)
       (let ((difference (- (account1 'balance)
                            (account2 'balance))))
         ((account1 'withdraw) difference)
         ((account2 'deposit) difference)))



• difference 변수에 값을 할당 후 withdraw,
  deposit 프로시저 호출 젂에 account1,
  account2의 balance가 변경될 수 있다.
해결 방법
• 두 계정의 줄 세우개를 사용해 exchange
  프로시저 젂체를 줄 세운 프로시저로 만든
  다.
• 계정 속의 줄 세우개를 밖으로 노출 시켜
  야 한다.
 – 모듈 방식이 깨짐
 – 현재로선 다른 방법이 없다.
(define (make-account-and-serializer balance)
  (define (withdraw amount)
    (if (>= balance amount)
        (begin (set! balance (- balance amount))
               balance)
        "Insufficient funds"))
  (define (deposit amount)
    (set! balance (+ balance amount))
    balance)
  (let ((balance-serializer (make-serializer)))
    (define (dispatch m)
      (cond ((eq? m 'withdraw) withdraw)
            ((eq? m 'deposit) deposit)
            ((eq? m 'balance) balance)
            ((eq? m 'serializer) balance-serializer)
            (else (error "Unknown request -- MAKE-ACCOUNT" m))))
    dispatch))
serialized-exchange
   (define (serialized-exchange account1 account2)
     (let ((serializer1 (account1 'serializer))
           (serializer2 (account2 'serializer)))
       ((serializer1 (serializer2 exchange))
        account1
        account2)))



• 두 계정의 줄 세우개 serializer1, serializer2
  를 사용해 exchange 프로시저 젂체를 줄
  세운 프로시저로 만들었다.
연습문제 3.44

돈을 맞바꾸는 문제처럼 transfer 프로시저 자체를 줄 세운 프로시저
로 만들어야 하는가?

      (define (transfer from-account to-account amount)
        ((from-account 'withdraw) amount)
        ((to-account 'deposit) amount))
연습문제 3.44 풀이
• 필요 없다.
• 돈을 맞바꾸는 경우에는 두 은행 계정의
  남은 돈의 차이를 계산한 후에 인터럽트가
  걸린 경우 두 은행 계정의 남은 돈 차이가
  변할 수 있기 때문에 돈을 맞바꾸는 프로
  시저 젂체를 줄 세운 프로시저로 만들었다.
• 돈을 옮기는 프로시저의 경우 인터럽트가
  걸려도 프로시저 동작에 이상 없다.
연습문제 3.45
serialized-exchange를 불러 쓸 때 어떤 일이 일어나는지 따져라

(define (make-account-and-serializer balance)
  (define (withdraw amount)
    (if (>= balance amount)
        (begin (set! balance (- balance amount))
                balance)
        "Insufficient funds"))
  (define (deposit amount)
    (set! balance (+ balance amount))
    balance)
  (let ((balance-serializer (make-serializer)))
    (define (dispatch m)
      (cond ((eq? m 'withdraw) (balance-serializer withdraw))
             ((eq? m 'deposit) (balance-serializer deposit))
             ((eq? m 'balance) balance)
             ((eq? m 'serializer) balance-serializer)
             (else (error "Unknown request -- MAKE-ACCOUNT" m))))
    dispatch))
연습문제 3.45 풀이
• serialized-exchange 프로시저는 두 계정의
  줄 세우개로 프로시저 젂체를 줄 세운 프
  로시저로 만든다.
• 안에서 exchange 프로시저를 실행하는데,
  withdraw, deposit 프로시저가 실행되지
  않고 하염없이 기다린다.
• 계정의 줄 세우개로 프로시저를 실행했기
  때문에.
make-serializer 구현
• 뮤텍스 (mutex)
 – mutual exclusion : 상호 배제
 – 뮤텍스 물체를 쥐거나(acquired) 풀어 주는
   (release) 연산
 – 한 프로세스가 뮤텍스를 잡으면 풀어 놓을 때
   까지 다른 프로세스가 뮤텍스를 잡지 못한다.
• 줄 세우개 하나에 뮤텍스 하나.
(define (make-serializer)
  (let ((mutex (make-mutex)))
    (lambda (p)
      (define (serialized-p . args)
        (mutex 'acquire)
        (let ((val (apply p args)))
          (mutex 'release)
          val))
      serialized-p)))
 (define (make-mutex)
  (let ((cell (list false)))
    (define (the-mutex m)
      (cond ((eq? m 'acquire)
             (if (test-and-set! cell)
                 (the-mutex 'acquire))) ; 재시도
            ((eq? m 'release) (clear! cell))))
    the-mutex))

(define (clear! cell)
  (set-car! cell false))
test-and-set! 구현
      (define (test-and-set! cell)
        (if (car cell)
            true
            (begin (set-car! cell true)
                   false)))


• 이렇게 구현하면 제대로 동작 안 한다.
• 병행성 제어를 집어넣어야 할 곳
• 한 알갱이로(atomically) 처리되어야 한다.
 – 하드웨어 수준에서 지원하는 프로시저를 사용.
 – MIT Scheme : without-interrupts
연습문제 3.47
세마포어(semaphore)를 뮤텍스와 test-and-set!을 써서 만
들어라.
- 잡았다 놓았다 하는 연산은 뮤텍스와 같지만 n개 프로세
스가 병행으로 세마포어를 쥘 수 있다.
- 뮤텍스를 사용하는 것만 풀이
연습문제 3.47 풀이
(define (new-make-semaphore n)
  (let ((count 0)
        (mutex (make-mutex)))
    (define (the-semaphore m)
      (cond ((eq? m 'acquire)
             (mutex 'acquire)
             (cond ((> count n)
                     (mutex 'release)
                     (the-semaphore 'acquire)) ; 재시도
                    (else
                     (set! count (+ count 1))
                     (mutex 'release))))
            ((eq? m 'release)
             (mutex 'acquire)
             (if (< count 0)
                  (set! count (- count 1)))
             (mutex 'release))))
    the-semaphore))
데드락 (deadlock)
• 여러 프로세스가 다른 프로세스를 지켜보
  면서 아무것도 하지 못하고 끝없이 기다려
  야 하는 상태
• 돈 맞바꾸는 문제의 경우에는 계정마다 번
  호를 매겨 놓고 모든 프로세스가 언제나
  번호가 낮은 계정을 움켜쥐고 일을 시작하
  도록 하면 해결 가능.
연습문제 3.48
계정에 번호를 매겨, 각 프로세스가 처음에 더 작은 번호
를 매긴 계정을 움켜쥐도록 만들어서 데드락을 피하는 기
법을 사용.
왜 돈 맞바꾸는 문제에서 데드락에 빠지지 않는가?
그 방법대로 serialized-exchange 프로시저를 작성.
연습문제 3.48 풀이
(define (make-account-and-serializer id balance)
  (define (withdraw amount)
    (if (>= balance amount)
        (begin (set! balance (- balance amount))
               balance)
        "Insufficient funds"))
  (define (deposit amount)
    (set! balance (+ balance amount))
    balance)
  (let ((balance-serializer (make-serializer)))
    (define (dispatch m)
      (cond ((eq? m 'withdraw) withdraw)
            ((eq? m 'deposit) deposit)
            ((eq? m 'balance) balance)
            ((eq? m 'id) id)
            ((eq? m 'serializer) balance-serializer)
            (else (error "Unknown request -- MAKE-ACCOUNT" m))))
    dispatch))
연습문제 3.48 풀이(계속)
(define (serialized-exchange account1 account2)
  (let ((serializer1 (account1 'serializer))
        (serializer2 (account2 'serializer)))
    (if (< (account1 'id) (account2 'id))
        ((serializer2 (serializer1 exchange)) account1 account2)
        ((serializer1 (serializer2 exchange)) account1 account2))))


• 비교 대상이 되는 id가 있어서 어떠한 계
  정 두개를 가져다 놓더라도 줄 세우는 방
  법은 한가지 밖에 없다. 그래서 데드락에
  빠지지 않는다.
[SICP] 3.4 Concurrency : Time is of the essence - 병행성 : 시간은 중요하다.

Más contenido relacionado

Similar a [SICP] 3.4 Concurrency : Time is of the essence - 병행성 : 시간은 중요하다.

Master slave pattern
Master slave patternMaster slave pattern
Master slave pattern
Heo Seungwook
 
120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장
tedypicker
 

Similar a [SICP] 3.4 Concurrency : Time is of the essence - 병행성 : 시간은 중요하다. (20)

R 시작해보기
R 시작해보기R 시작해보기
R 시작해보기
 
파이썬 스터디 2주차
파이썬 스터디 2주차파이썬 스터디 2주차
파이썬 스터디 2주차
 
Clojure Monad
Clojure MonadClojure Monad
Clojure Monad
 
Clojure Chapter.6
Clojure Chapter.6Clojure Chapter.6
Clojure Chapter.6
 
7가지 동시성 모델 4장
7가지 동시성 모델 4장7가지 동시성 모델 4장
7가지 동시성 모델 4장
 
R 기본-데이타형 소개
R 기본-데이타형 소개R 기본-데이타형 소개
R 기본-데이타형 소개
 
3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택3ds maxscript 튜토리얼_20151206_서진택
3ds maxscript 튜토리얼_20151206_서진택
 
7장매크로
7장매크로7장매크로
7장매크로
 
Master slave pattern
Master slave patternMaster slave pattern
Master slave pattern
 
[홍대 머신러닝 스터디 - 핸즈온 머신러닝] 2장. 머신러닝 프로젝트 처음부터 끝까지
[홍대 머신러닝 스터디 - 핸즈온 머신러닝] 2장. 머신러닝 프로젝트 처음부터 끝까지[홍대 머신러닝 스터디 - 핸즈온 머신러닝] 2장. 머신러닝 프로젝트 처음부터 끝까지
[홍대 머신러닝 스터디 - 핸즈온 머신러닝] 2장. 머신러닝 프로젝트 처음부터 끝까지
 
[devil's camp] - 알고리즘 대회와 STL (박인서)
[devil's camp] - 알고리즘 대회와 STL (박인서)[devil's camp] - 알고리즘 대회와 STL (박인서)
[devil's camp] - 알고리즘 대회와 STL (박인서)
 
확통 회귀분석
확통 회귀분석확통 회귀분석
확통 회귀분석
 
NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현
 
Scalability
ScalabilityScalability
Scalability
 
Scala, Scalability
Scala, ScalabilityScala, Scalability
Scala, Scalability
 
R 프로그래밍-향상된 데이타 조작
R 프로그래밍-향상된 데이타 조작R 프로그래밍-향상된 데이타 조작
R 프로그래밍-향상된 데이타 조작
 
자료구조02
자료구조02자료구조02
자료구조02
 
120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장120908 레거시코드활용전략 4장5장
120908 레거시코드활용전략 4장5장
 
7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍
 
알고리즘2
알고리즘2알고리즘2
알고리즘2
 

Más de 종빈 오

내가 본 미드 이야기
내가 본 미드 이야기내가 본 미드 이야기
내가 본 미드 이야기
종빈 오
 
비트 경제와 공짜
비트 경제와 공짜비트 경제와 공짜
비트 경제와 공짜
종빈 오
 
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
종빈 오
 
[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스
종빈 오
 
Intrusive data structure 소개
Intrusive data structure 소개Intrusive data structure 소개
Intrusive data structure 소개
종빈 오
 
2011 아꿈사 오전반 포스트모템
2011 아꿈사 오전반 포스트모템2011 아꿈사 오전반 포스트모템
2011 아꿈사 오전반 포스트모템
종빈 오
 
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
종빈 오
 
[GEG1] 3.volumetric representation of virtual environments
[GEG1] 3.volumetric representation of virtual environments[GEG1] 3.volumetric representation of virtual environments
[GEG1] 3.volumetric representation of virtual environments
종빈 오
 
넘쳐나는 정보 소화 노하우
넘쳐나는 정보 소화 노하우넘쳐나는 정보 소화 노하우
넘쳐나는 정보 소화 노하우
종빈 오
 
[Domain driven design] 17장 전략의 종합
[Domain driven design] 17장 전략의 종합[Domain driven design] 17장 전략의 종합
[Domain driven design] 17장 전략의 종합
종빈 오
 
LevelDB 간단한 소개
LevelDB 간단한 소개LevelDB 간단한 소개
LevelDB 간단한 소개
종빈 오
 
[GEG1] 2.the game asset pipeline
[GEG1] 2.the game asset pipeline[GEG1] 2.the game asset pipeline
[GEG1] 2.the game asset pipeline
종빈 오
 
[TAOCP] 2.5 동적인 저장소 할당
[TAOCP] 2.5 동적인 저장소 할당[TAOCP] 2.5 동적인 저장소 할당
[TAOCP] 2.5 동적인 저장소 할당
종빈 오
 
[GEG1] 24. key value dictionary
[GEG1] 24. key value dictionary[GEG1] 24. key value dictionary
[GEG1] 24. key value dictionary
종빈 오
 
[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬
종빈 오
 
[TAOCP] 1.3.1 MIX 설명
[TAOCP] 1.3.1 MIX 설명[TAOCP] 1.3.1 MIX 설명
[TAOCP] 1.3.1 MIX 설명
종빈 오
 
[GEG1] 10.camera-centric engine design for multithreaded rendering
[GEG1] 10.camera-centric engine design for multithreaded rendering[GEG1] 10.camera-centric engine design for multithreaded rendering
[GEG1] 10.camera-centric engine design for multithreaded rendering
종빈 오
 
[TAOCP] 1.3.1 MIX 설명, 짝수 연습문제 풀이
[TAOCP] 1.3.1 MIX 설명, 짝수 연습문제 풀이[TAOCP] 1.3.1 MIX 설명, 짝수 연습문제 풀이
[TAOCP] 1.3.1 MIX 설명, 짝수 연습문제 풀이
종빈 오
 

Más de 종빈 오 (20)

적당한 스터디 발표자료 만들기 2.0
적당한 스터디 발표자료 만들기 2.0적당한 스터디 발표자료 만들기 2.0
적당한 스터디 발표자료 만들기 2.0
 
페리 수열(Farey sequence)
페리 수열(Farey sequence)페리 수열(Farey sequence)
페리 수열(Farey sequence)
 
내가 본 미드 이야기
내가 본 미드 이야기내가 본 미드 이야기
내가 본 미드 이야기
 
비트 경제와 공짜
비트 경제와 공짜비트 경제와 공짜
비트 경제와 공짜
 
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
[NDC12] 게임 물리 엔진의 내부 동작 원리 이해
 
[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스
 
Intrusive data structure 소개
Intrusive data structure 소개Intrusive data structure 소개
Intrusive data structure 소개
 
2011 아꿈사 오전반 포스트모템
2011 아꿈사 오전반 포스트모템2011 아꿈사 오전반 포스트모템
2011 아꿈사 오전반 포스트모템
 
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
[프로젝트가 서쪽으로 간 까닭은] chap 17, 18, 26, 33, 81
 
[GEG1] 3.volumetric representation of virtual environments
[GEG1] 3.volumetric representation of virtual environments[GEG1] 3.volumetric representation of virtual environments
[GEG1] 3.volumetric representation of virtual environments
 
넘쳐나는 정보 소화 노하우
넘쳐나는 정보 소화 노하우넘쳐나는 정보 소화 노하우
넘쳐나는 정보 소화 노하우
 
[Domain driven design] 17장 전략의 종합
[Domain driven design] 17장 전략의 종합[Domain driven design] 17장 전략의 종합
[Domain driven design] 17장 전략의 종합
 
LevelDB 간단한 소개
LevelDB 간단한 소개LevelDB 간단한 소개
LevelDB 간단한 소개
 
[GEG1] 2.the game asset pipeline
[GEG1] 2.the game asset pipeline[GEG1] 2.the game asset pipeline
[GEG1] 2.the game asset pipeline
 
[TAOCP] 2.5 동적인 저장소 할당
[TAOCP] 2.5 동적인 저장소 할당[TAOCP] 2.5 동적인 저장소 할당
[TAOCP] 2.5 동적인 저장소 할당
 
[GEG1] 24. key value dictionary
[GEG1] 24. key value dictionary[GEG1] 24. key value dictionary
[GEG1] 24. key value dictionary
 
[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬
 
[TAOCP] 1.3.1 MIX 설명
[TAOCP] 1.3.1 MIX 설명[TAOCP] 1.3.1 MIX 설명
[TAOCP] 1.3.1 MIX 설명
 
[GEG1] 10.camera-centric engine design for multithreaded rendering
[GEG1] 10.camera-centric engine design for multithreaded rendering[GEG1] 10.camera-centric engine design for multithreaded rendering
[GEG1] 10.camera-centric engine design for multithreaded rendering
 
[TAOCP] 1.3.1 MIX 설명, 짝수 연습문제 풀이
[TAOCP] 1.3.1 MIX 설명, 짝수 연습문제 풀이[TAOCP] 1.3.1 MIX 설명, 짝수 연습문제 풀이
[TAOCP] 1.3.1 MIX 설명, 짝수 연습문제 풀이
 

[SICP] 3.4 Concurrency : Time is of the essence - 병행성 : 시간은 중요하다.

  • 1. 3.4 Concurrency: Time Is of the Essence 병행성 : 시간은 중요하다 http://ohyecloudy.com http://cafe.naver.com/architect1.cafe 2009.3.14
  • 2. 덮어쓰기 연산 (withdraw 25) • 물체에 상태를 부여 75 • 계산 방법에 시갂 개념 추가 (withdraw 25) 50 • 만약 없다면 시갂의 영향을 받지 않고 한결같아 진다.
  • 3. 병행 시스템에서 시간의 본질 (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) 100 잔액 조회 : 100 잔액 조회 : 100 새 값 : 100 – 10 = 90 새 값 : 100 – 25 = 75 잔액을 90으로 set! 90 잔액을 75로 set! 75
  • 4. 병행 프로그램의 올바른 동작 • 변수 하나에 여러 프로세스가 값을 덮어쓰 려고 하는게 문제를 복잡하게 하고 있다. • 상태 변화가 병행으로 일어날 때 예측 가 능하게 동작하도록 병행 처리에 제약을 준 다.
  • 5. 병행 처리에 제약을 주는 방법 • 상태 변수 하나를 같이 사용 – 값을 바꿀 수 있는 연산 두 개가 동시에 돌아가지 못하게 제약 • 차례대로 돌아가게 만들어 병행 프로그램과 같은 결과를 만들어 낸다. – 어떤 차례인지 결정하지 않으면 올바른 결과가 여 러 개다. • 열의 퍼짐 시뮬레이션(flow of heat in an object) – 여러 개의 프로세스 – 자기 값과 이웃 값의 평균으로 자기 값 수정 – 되풀이 하다보면 올바른 값으로 수렴
  • 6. 병행 프로세스를 다루기 어려운 까닭 • 여러 프로세스에서 일어나는 사건의 차례 가 서로 뒤엉킬 수 있기 때문 • 모든 경우를 하나하나 따져봐야 한다. • 사건이 많아질수록 경우의 수가 폭발적으 로 증가한다. – (a,b,c,d,e,f) 사건이 차례대로 일어나는 A 프로 세스와 (x,y,z,w) 사건이 차례대로 일어나는 B 프로세스가 있다면???
  • 7. parallel-execute (define x 10) (parallel-execute (lambda () (set! x (* x x))) ; P1 (lambda () (set! x (+ x 1)))) ; P2 P1 : a (첫 번째 x 읽기), b (두 번째 x 읽기), c (x를 덮어쓰기) P2 : ㄱ (x 읽기), ㄴ (x를 덮어쓰기) 두 프로세스가 끝난 다음 나올 수 있는 x의 값 101 : a  b  c  ㄱ  ㄴ 121 : ㄱ  ㄴ  a  b  c 110 : a  ㄱ  ㄴ  b  c 11 : ㄱ  a  b  c  ㄴ 100 : a  b  ㄱ  ㄴ  c
  • 8. 병행성을 다스리는 방법 • 서로 뒤엉켜 돌아가는 여러 프로세스에 어 떤 제약을 걸어서, 프로그램이 제대로 돌 아갂다고 믿을 수 있도록 병행 시스템을 설계하는 방법이 필요하다. • 줄 세우개(serializer)가 한가지 방법.
  • 9. 줄 세우개(serializer) • 병행으로 돌아가지 못하는 프로시저를 정 의 • 여러 프로세스가 함께 쓰는 변수를 다스릴 수 있다.
  • 10. make-serializer (define x 10) (define s (make-serializer)) (parallel-execute (s (lambda () (set! x (* x x)))) ; P1 (s (lambda () (set! x (+ x 1))))) ; P2 P1 : a (첫 번째 x 읽기), b (두 번째 x 읽기), c (x를 덮어쓰기) P2 : ㄱ (x 읽기), ㄴ (x를 덮어쓰기) 두 프로세스가 끝난 다음 나올 수 있는 x의 값 101 : a  b  c  ㄱ  ㄴ 121 : ㄱ  ㄴ  a  b  c 110 : a  ㄱ  ㄴ  b  c 11 : ㄱ  a  b  c  ㄴ 100 : a  b  ㄱ  ㄴ  c
  • 11. 줄 세우개를 사용한 은행 계정 • 잒액을 변경하는 withdraw, deposit 프로 시저를 같은 줄 세우개를 사용해 동시에 실행할 수 없게 제한했다. • 줄 세우개는 계정마다 하나씩 가진다. – 서로 다른 계정의 작업은 병행으로 이루어진 다.
  • 12. (define (make-account balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (let ((protected (make-serializer))) (define (dispatch m) (cond ((eq? m 'withdraw) (protected withdraw)) ((eq? m 'deposit) (protected deposit)) ((eq? m 'balance) balance) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch))
  • 13. 연습 3.41 balance에 손을 댈 때 줄 세우기를 하지 않으면 제대로 돌아가지 않을 수도 있다는데 동의? (define (make-account balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (let ((protected (make-serializer))) (define (dispatch m) (cond ((eq? m 'withdraw) (protected withdraw)) ((eq? m 'deposit) (protected deposit)) ((eq? m 'balance) ((protected (lambda () balance)))) ; serialized (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch))
  • 14. 연습 3.41 풀이 • 줄 세우기를 한 결과 withdraw, deposit과 balance는 동시에 실행되지 않는다. • balance는 값을 변경하는 동작이 아니라 값을 읽는 동작을 하는 프로시저. • Ben은 balance를 거래 후 잒액으로 생각. • 동의하지 않음. • balance 프로시저를 실행하는 그 시갂에 잒액을 보여줘야 한다고 생각한다.
  • 15. 연습 3.42 이렇게 만들어도 괜찮은가? 변경 젂 make-account와 병행성에 어떤 차이가 나는가? (define (make-account balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (let ((protected (make-serializer))) (let ((protected-withdraw (protected withdraw)) (protected-deposit (protected deposit))) (define (dispatch m) (cond ((eq? m 'withdraw) protected-withdraw) ((eq? m 'deposit) protected-deposit) ((eq? m 'balance) balance) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch)))
  • 16. 연습 3.42 풀이 • 상관 없다. • 이젂과 상관없이 make-serializer는 은행 계정 하나당 하나가 존재한다. • make-serializer 프로시저를 실행하는 프로시 저를 미리 만들어서 같은 프로시저를 내놓는 다고 하더라도 줄 세운 프로시저가 같이 쓰는 뮤텍스와 같은 동기화 수단에 의존하기 때문 • 그렇기 때문에 병행성 또한 차이가 없다. • 뒤에 make-serializer 구현 참조.
  • 17. 여러 자원을 함께 쓰는 문제 • 이제 까지 자원 하나를 여럾이 쓰는 예제. – 폴과 피터가 같이 쓰는 생활비 은행 계좌 • 여러 자원을 함께 쓰는 경우를 살펴보자. – 두 은행 계정의 남은 돈을 맞바꾸는 일.
  • 18. exchange (define (exchange account1 account2) (let ((difference (- (account1 'balance) (account2 'balance)))) ((account1 'withdraw) difference) ((account2 'deposit) difference))) • difference 변수에 값을 할당 후 withdraw, deposit 프로시저 호출 젂에 account1, account2의 balance가 변경될 수 있다.
  • 19. 해결 방법 • 두 계정의 줄 세우개를 사용해 exchange 프로시저 젂체를 줄 세운 프로시저로 만든 다. • 계정 속의 줄 세우개를 밖으로 노출 시켜 야 한다. – 모듈 방식이 깨짐 – 현재로선 다른 방법이 없다.
  • 20. (define (make-account-and-serializer balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (let ((balance-serializer (make-serializer))) (define (dispatch m) (cond ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) ((eq? m 'balance) balance) ((eq? m 'serializer) balance-serializer) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch))
  • 21. serialized-exchange (define (serialized-exchange account1 account2) (let ((serializer1 (account1 'serializer)) (serializer2 (account2 'serializer))) ((serializer1 (serializer2 exchange)) account1 account2))) • 두 계정의 줄 세우개 serializer1, serializer2 를 사용해 exchange 프로시저 젂체를 줄 세운 프로시저로 만들었다.
  • 22. 연습문제 3.44 돈을 맞바꾸는 문제처럼 transfer 프로시저 자체를 줄 세운 프로시저 로 만들어야 하는가? (define (transfer from-account to-account amount) ((from-account 'withdraw) amount) ((to-account 'deposit) amount))
  • 23. 연습문제 3.44 풀이 • 필요 없다. • 돈을 맞바꾸는 경우에는 두 은행 계정의 남은 돈의 차이를 계산한 후에 인터럽트가 걸린 경우 두 은행 계정의 남은 돈 차이가 변할 수 있기 때문에 돈을 맞바꾸는 프로 시저 젂체를 줄 세운 프로시저로 만들었다. • 돈을 옮기는 프로시저의 경우 인터럽트가 걸려도 프로시저 동작에 이상 없다.
  • 24. 연습문제 3.45 serialized-exchange를 불러 쓸 때 어떤 일이 일어나는지 따져라 (define (make-account-and-serializer balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (let ((balance-serializer (make-serializer))) (define (dispatch m) (cond ((eq? m 'withdraw) (balance-serializer withdraw)) ((eq? m 'deposit) (balance-serializer deposit)) ((eq? m 'balance) balance) ((eq? m 'serializer) balance-serializer) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch))
  • 25. 연습문제 3.45 풀이 • serialized-exchange 프로시저는 두 계정의 줄 세우개로 프로시저 젂체를 줄 세운 프 로시저로 만든다. • 안에서 exchange 프로시저를 실행하는데, withdraw, deposit 프로시저가 실행되지 않고 하염없이 기다린다. • 계정의 줄 세우개로 프로시저를 실행했기 때문에.
  • 26. make-serializer 구현 • 뮤텍스 (mutex) – mutual exclusion : 상호 배제 – 뮤텍스 물체를 쥐거나(acquired) 풀어 주는 (release) 연산 – 한 프로세스가 뮤텍스를 잡으면 풀어 놓을 때 까지 다른 프로세스가 뮤텍스를 잡지 못한다. • 줄 세우개 하나에 뮤텍스 하나.
  • 27. (define (make-serializer) (let ((mutex (make-mutex))) (lambda (p) (define (serialized-p . args) (mutex 'acquire) (let ((val (apply p args))) (mutex 'release) val)) serialized-p))) (define (make-mutex) (let ((cell (list false))) (define (the-mutex m) (cond ((eq? m 'acquire) (if (test-and-set! cell) (the-mutex 'acquire))) ; 재시도 ((eq? m 'release) (clear! cell)))) the-mutex)) (define (clear! cell) (set-car! cell false))
  • 28. test-and-set! 구현 (define (test-and-set! cell) (if (car cell) true (begin (set-car! cell true) false))) • 이렇게 구현하면 제대로 동작 안 한다. • 병행성 제어를 집어넣어야 할 곳 • 한 알갱이로(atomically) 처리되어야 한다. – 하드웨어 수준에서 지원하는 프로시저를 사용. – MIT Scheme : without-interrupts
  • 29. 연습문제 3.47 세마포어(semaphore)를 뮤텍스와 test-and-set!을 써서 만 들어라. - 잡았다 놓았다 하는 연산은 뮤텍스와 같지만 n개 프로세 스가 병행으로 세마포어를 쥘 수 있다. - 뮤텍스를 사용하는 것만 풀이
  • 30. 연습문제 3.47 풀이 (define (new-make-semaphore n) (let ((count 0) (mutex (make-mutex))) (define (the-semaphore m) (cond ((eq? m 'acquire) (mutex 'acquire) (cond ((> count n) (mutex 'release) (the-semaphore 'acquire)) ; 재시도 (else (set! count (+ count 1)) (mutex 'release)))) ((eq? m 'release) (mutex 'acquire) (if (< count 0) (set! count (- count 1))) (mutex 'release)))) the-semaphore))
  • 31. 데드락 (deadlock) • 여러 프로세스가 다른 프로세스를 지켜보 면서 아무것도 하지 못하고 끝없이 기다려 야 하는 상태 • 돈 맞바꾸는 문제의 경우에는 계정마다 번 호를 매겨 놓고 모든 프로세스가 언제나 번호가 낮은 계정을 움켜쥐고 일을 시작하 도록 하면 해결 가능.
  • 32. 연습문제 3.48 계정에 번호를 매겨, 각 프로세스가 처음에 더 작은 번호 를 매긴 계정을 움켜쥐도록 만들어서 데드락을 피하는 기 법을 사용. 왜 돈 맞바꾸는 문제에서 데드락에 빠지지 않는가? 그 방법대로 serialized-exchange 프로시저를 작성.
  • 33. 연습문제 3.48 풀이 (define (make-account-and-serializer id balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (let ((balance-serializer (make-serializer))) (define (dispatch m) (cond ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) ((eq? m 'balance) balance) ((eq? m 'id) id) ((eq? m 'serializer) balance-serializer) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch))
  • 34. 연습문제 3.48 풀이(계속) (define (serialized-exchange account1 account2) (let ((serializer1 (account1 'serializer)) (serializer2 (account2 'serializer))) (if (< (account1 'id) (account2 'id)) ((serializer2 (serializer1 exchange)) account1 account2) ((serializer1 (serializer2 exchange)) account1 account2)))) • 비교 대상이 되는 id가 있어서 어떠한 계 정 두개를 가져다 놓더라도 줄 세우는 방 법은 한가지 밖에 없다. 그래서 데드락에 빠지지 않는다.