Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

동시성 프로그래밍 하기 좋은 Clojure

5,690 views

Published on

제5회 Lisp 세미나에서 발표한 "동시성 프로그래밍 하기 좋은 Clojure" 발표 자료

Published in: Software
  • Be the first to comment

동시성 프로그래밍 하기 좋은 Clojure

  1. 1. 동시성 프로그래밍하기 자바보다 좋은 Clojure / 김은민
  2. 2. 왜 이런 주제를? • 7가지 동시성 모델
  3. 3. 이야기 할 내용 1. 동시에 값 하나를 바꾸는 좋은 방법 - Atom 2. 동시에 값 여럿을 바꾸는 좋은 방법 - Ref 3. 적은 리소스를 사용해서 동시 작업 간에 타이밍을 맞추는 방법 - core.async
  4. 4. Atom 1. 동시에 값 하나를 바꾸는 좋은 방법
  5. 5. 스레드 안전하지 않은 Counter 코드 ????????
  6. 6. 스레드 안전하지 않은 Counter 코드 바이트 코드 읽고 - 바꾸고 - 쓰고
  7. 7. 스레드 안전한 Counter 코드 ???
  8. 8. 스레드 안전한 Counter 코드 ??? 동기화 되지 않으면 메인 메모리에 쓰여지지 않고 CPU 캐시에 남은 값이 읽힐 수 있다.
  9. 9. 스레드 안전한 Counter 코드
  10. 10. synchronized (Monitor) • synchronized는 Tony Hoare가 고안한 Monitor라는 방식의 동기화 방법이다. • 자바의 synchronized는 한번에 하나의 스레드가 접근 하기 위해 락을 사용한다.
  11. 11. 락의 문제 • 스레드 경합이 없는 단일 스레드에서 락을 얻고 반납하는 일은 부하다. • 락을 얻지 못하고 대기 해야하는 스레드가 많아지면 스레드 전환에 들어가는 비용 이 많아진다. • 락은 다양한 활동성 문제(데드락, 라이브락, 소모)를 일으킬 수 있다.
  12. 12. 자바 병렬 프로그래밍 ‘병렬 알고리즘과 관련한 최근 연구 결과를 보면 대부분이 
 넌블로킹 알고리즘, 즉 여러 스레드가 동작하는 환경에서 
 데이터의 안정성을 보장하는 방법으로 락을 사용하는 
 대신 저수준의 하드웨어에서 제공하는 
 비교 후 교환 등의 명령을 사용하는 알고리즘을 다루고 있다.’
  13. 13. 병렬 연산을 위한 하드웨어적인 지원 • 현대 프로세서는 CAS(Compare-and-swap) 연산을 제공한다. • x86의 CMPXCHG instruction (ex. CMPXCHG r/m8,r8) • CAS 연산은 값을 변경하기 위해 기존 값과 새 값을 하나의 명령어로 수행한다. • 만약 기존 값이 변경 하려는 값과 같으면 새 값으로 바꾼다. • CAS count, 1, 2 ( 기존 값이 1이면 2로 바꾼다. 그렇지 않으면 아무일도 하지 않는다.) • 스레드 경쟁이 없다면 CAS 연산은 락을 사용하는 연산 보다 2배 빠르다. 
 - 자바 병렬 프로그래밍 15장 • 자바는 java.util.Concurrent.atomic 패키지에 AtomicXxx 클래스에서 CAS연산 을 지원한다. • C는 <stdatomic.h>에서 지원한다.
  14. 14. Atomic 클래스를 사용한 넌블로킹 Counter newValue를 쓰려고 했는데 누군가 값을 바꿔 oldValue와 다르면 false!
 그럼 다시 oldValue를 읽어서 시도한다.
  15. 15. 락과 넌블로킹 성능 비교 1. 스래드 경쟁이 심한 경우 Lock > Atomic 2. 스래드 경쟁이 일반 적인 경우 Lock < Atomic
  16. 16. 클로저 스레드
  17. 17. 클로저의 atom을 이용한 넌블로킹 Counter
  18. 18. 클로저의 atom을 이용한 넌블로킹 Counter
  19. 19. 클로저의 atom을 이용한 넌블로킹 Counter
  20. 20. Ref 2. 동시에 값 여럿을 바꾸는 좋은 방법
  21. 21. 자바 병렬 프로그래밍 ‘병렬 알고리즘과 관련한 최근 연구 결과를 보면 대부분이 
 넌블로킹 알고리즘, 즉 여러 스레드가 동작하는 환경에서 
 데이터의 안정성을 보장하는 방법으로 
 락을 사용하는 대신 …’
  22. 22. MVCC (Multiversion connurrency control) • Multiversion concurrency control (MCC or MVCC), is a concurrency control method commonly used by database management systems to provide concurrent access to the database and in programming languages to implement transactional memory.
 …
 MVCC provides point in time consistent views. Read transactions under MVCC typically use a timestamp or transaction ID to determine what state of the DB to read, and read these versions of the data. Read and write transactions are thus isolated from each other without any need for locking. Writes create a newer version, while concurrent reads access the older version. • 구현이 힘들어 자바 예제는 생략합니다. ㅜㅠ
  23. 23. • 클로저 Ref는 STM을 이용한 MVCC 방식의 트랜잭션 기능 • 예제 • checking 계좌에 1만원 • savings 계좌에 2만원 • checking 계좌에서 savings 계좌로 100원씩 100번 1만원 보낸다. • savings 계좌에서 checking 계좌로 200원씩 100번 2만원 보낸다. • 결국 savings 계좌에서 checking 계좌로 1만원 보낸다. 클로저 Ref 예제
  24. 24. 클로저 Ref 예제
  25. 25. 클로저 Ref 예제 200번이 아니다! 299번은 재시도 되었다.
  26. 26. core.async 3. 적은 리소스를 사용해서 동시 작업 간에 
 타이밍을 맞추는 방법
  27. 27. Latch를 이용한 스레드 동기화 • java.util.concurrent 패키지에 Latch 지원 클래스가 있다. • 예제 • Worker1은 1초에 한번씩 10회 화면에 횟수를 출력한다. • Worker2는 기다렸다가 Worker1이 5회가 되면 1초에 한번씩 10회 화면에 횟 수를 출력한다. • Worker1과 Worker2는 동시에 시작하지만 Worker2는 Worker1이 5회가 될 때까지 기다려야 한다.
  28. 28. Latch를 이용한 스레드 동기화 예제 - Worker1
  29. 29. Latch를 이용한 스레드 동기화 예제 - Worker2 latch가 0이 될때 까지 블로킹
  30. 30. Latch를 이용한 스레드 동기화 예제
  31. 31. Future를 이용한 스레드 동기화 • java.util.concurrent 패키지에 Future 관련 클래스가 있다. • 예제 • Worker1은 0부터 9까지 합을 구한다. • Worker2는 기다렸다가 Worker1의 결과에 0부터 9까지 합을 더한다. • Worker1과 Worker2는 동시에 시작하지만 Worker2는 Worker1이 결과를 줄 때까지 기다린다.
  32. 32. Future를 이용한 스레드 동기화 - Worker1
  33. 33. Future를 이용한 스레드 동기화 - Worker2 Worker1 작업이 끝나고 결과가 나올 때 까지 블로킹
  34. 34. Future를 이용한 스레드 동기화
  35. 35. 클로저 future @는 Future.get이므로 future가 종료될 때까지 블로킹
  36. 36. 클로저 future
  37. 37. 클로저 future와 promise 프로그램이 끝나지 않도록 블로킹하며 
 future가 끝나기를 기다린다.
  38. 38. 자바 병렬 프로그래밍 ‘병렬 알고리즘과 관련한 최근 연구 결과를 보면 대부분이 
 넌블로킹 알고리즘, 즉 여러 스레드가 동작하는 환경에서 
 데이터의 안정성을 보장하는 방법으로 …’
  39. 39. 다시 넌블로킹 • future와 promise는 작업을 블로킹 하면서 타이밍을 맞춘다. • 스레드가 많이 블로킹되면 대기하는 스레드가 많아져 리소스가 낭비된다. • 블로킹 대신 스레드를 종료하고 이벤트를 기다렸다 다시 스레드를 실행하는 
 이벤트 방식은 효율적이다.
  40. 40. 자바 이벤트 기반 예제 onCreate 스레드는 종료된다. 클릭 이벤트가 발생하면 다음 로직을 실행한다.
  41. 41. 하지만 콜백 헬…
  42. 42. core.async • 클로저 CSP(Communicating sequential processes - Tony Hoare 1977) 
 라이브러리 • 채널 기반의 동시성 흐름 제어 패턴 • Go 언어에서 기본 동시성 기능으로 제공
  43. 43. core.async • 채널 체널에 값이 들어올 때 까지 블로킹 체널에 값을 쓴다
  44. 44. core.async • 신비스러운 Go 루틴 스레드 풀에서 가져온 스레드에서 채널에 값이 들어오길 기다리는 
 이벤트 핸들러를 만들고 스레드 종료 채널에 값이 들어오면 스레드 풀에서 스레드를 가져와 x에 값을 설정하고 다시 채널에 값이 들어오길 기다리는 이벤트 핸들러를 만들고 스레드 종료채널에 값이 들어오면 스레드를 풀에서 가져와서 y에 값을 설정하고 x와 y를 더한 값을 출력하고 스레드 종료
  45. 45. core.async • 논블록킹 방식으로 주어진 웹 페이지의 단어 수 세기 넌블로킹과 순차흐름의 장점을 모두 가질 수 있다. 대기하는 동안 스레드를 점유하지 않기 때문에 적은 리소스를 사용하는 효율적인 코드를 작성할 수 있다.
  46. 46. 아쉽지만 능력 부족으로 다루지 못한 내용 • 함수형 프로그래밍과 동시성 • pmap, reducer, transducer … & Rx • Functional Reactive Programing • CSP
  47. 47. 결론으로 가는 중 • 저수준 언어에서 제공하는 스레드와 락 같은 기본 동시성 기능은 
 요즘 같은 멀티 코어 환경에서 많은 노력을 해야 재대로 코드를 작성할 수 있다. • java.concurrent 패키지 처럼 동시성 관련 라이브러리를 사용하는 것이 좋다. • 하지만 언어의 기본 기능으로 제공되는 편리한 스레드와 락의 유혹에서 벗어나기 어렵다. • 현대 프로그래밍 언어들을 기본 언어 기능으로 훌륭한 동시성 기능을 제공한다.
  48. 48. 진짜 결론 • 1958년에 고안된 Lisp(클로저)은 저수준 언어인가? • 라이브러리를 사용하는 것보다 언어에서 제공해야 하는 것이 아닌가? • Lisp의 s-expression은 시대를 초월한다.
  49. 49. Thanks (quantum-process …

×