소프트웨어 트랜잭션 메모리의 구성 예


11

항상 언급되는 소프트웨어 트랜잭션 메모리의 주요 장점 중 하나는 구성 성 및 모듈성입니다. 더 큰 부품을 생산하기 위해 다른 조각을 결합 할 수 있습니다. 잠금 기반 프로그램에서는 종종 그렇지 않습니다.

실제 코드로 이것을 보여주는 간단한 예제를 찾고 있습니다. Clojure의 예제를 선호하지만 Haskell도 좋습니다. 예제에 쉽게 구성 할 수없는 일부 잠금 기반 코드가있는 경우 보너스 포인트.


1
흥미롭지 만 StackOverflow 질문처럼 들립니다.
Steve

이 질문은 4 분 후에 요청되었습니다. stackoverflow.com/questions/5518546/… 누군가가이 질문을 마이그레이션하고 병합합니까 (가능한 경우)?
Job

예, 여기에 게시 한 후에 아마도 Stackoverflow에서 더 좋을 것임을 깨달았습니다. 누군가가 그것을 합칠 수 있다면 나에게도 괜찮습니다.
dbyrne

답변:


9

은행 계좌가 있다고 가정하십시오.

(def accounts 
 [(ref 0) 
  (ref 10) 
  (ref 20) 
  (ref 30)])

그리고 원자 "전달"기능 :

(defn transfer [src-account dest-account amount]
  (dosync
    (alter dest-account + amount)
    (alter src-account - amount)))

다음과 같이 작동합니다.

(transfer (accounts 1) (accounts 0) 5)

(map deref accounts)
=> (5 5 20 30)

그런 다음 이체 기능을 쉽게 구성하여 여러 계정에서 이체하는 등 더 높은 수준의 거래를 만들 수 있습니다.

(defn transfer-from-all [src-accounts dest-account amount]
  (dosync
    (doseq [src src-accounts] 
      (transfer src dest-account amount))))

(transfer-from-all 
  [(accounts 0) (accounts 1) (accounts 2)] 
  (accounts 3) 
  5)

(map deref accounts)
=> (0 0 15 45)

모든 복수 전송은 단일의 결합 된 트랜잭션에서 발생했습니다. 즉, 작은 트랜잭션을 "구성"할 수있었습니다.

잠금으로이 작업을 수행하려면 매우 빠르게 복잡해집니다. 계정을 개별적으로 잠글 필요가 있다고 가정하면 교착 상태를 피하기 위해 잠금 획득 순서에 프로토콜을 설정하는 것과 같은 작업을 수행해야합니다. 감지하기 어려운 실수를하는 것은 매우 쉽습니다. STM은이 모든 고통을 덜어줍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.