답변:
이 질문에 대한 실제 답변을 위해 "The Joy of Clojure"또는 "programming Clojure"를 적극 권장합니다. 각각에 대한 동기에 대한 짧은 내용을 재현 할 수 있습니다.
정체성의 개념에 대한이 비디오를 시청 하거나 여기서 공부하십시오 .
조정 된 액세스는 두 ID가 함께 변경되어야 할 때 사용됩니다. 전형적인 예는 한 은행 계좌에서 다른 은행 계좌로 돈을 이동하는 것입니다. 완전히 이동하거나 전혀 이동하지 않아야합니다.
조정되지 않은 액세스는 하나의 ID 만 업데이트해야 할 때 사용되며 이는 매우 일반적인 경우입니다.
계속하기 전에 모든 ID가 정산 될 때까지 호출이 대기 할 것으로 예상되는 경우 동기 액세스가 사용됩니다.
비동기 액세스는 "실행 후 잊어 버리기"이며 ID가 자신의 시간에 새로운 상태에 도달하도록합니다.
ensure
기능을 보다 명확하고 효율적으로 만들려면 clojure.github.io/clojure/clojure.core-api.html#clojure.core/… 함수를 사용하는 것이 좋습니다.
Ref는 스레드간에 동기화되어야하는 상태를위한 것입니다. 여러 가지를 추적해야하고 여러 가지를 한 번에 작성하는 작업을 수행해야하는 경우가있는 경우 refs를 사용하십시오. 여러 다른 상태가있을 때마다 ref를 사용하는 것은 나쁜 생각이 아닙니다.
Atom은 스레드간에 동기화되어야하는 독립 상태를위한 것입니다. 원자의 상태와 다른 것을 동시에 변경할 필요가 없다면 at atom을 사용하는 것이 안전합니다 (특히 전체 프로그램에 상태가 하나만있는 경우 원자에 넣을 수 있습니다). . 사소하지 않은 예로서 함수의 반환 값을 캐시 (즉, 메모)하려는 경우 원자를 사용하는 것이 안전 할 수 있습니다. 상태는 함수 외부의 모든 항목에 표시되지 않으므로 걱정할 필요가 없습니다. 함수 내부의 상태 변경에 대해
에이전트의 주요 요점은 다른 스레드에서 실행된다는 것입니다. 에이전트의 값을 가져 와서 해당 값에 함수를 적용하도록 지시 할 수 있지만 함수가 언제 실행 될지 또는 함수가 적용될 값을 알 수 없습니다.
Vars는 스레드별로 무언가를 저장해야 할 때 사용됩니다. 다중 스레드 프로그램이 있고 각 스레드에 자체 개인 상태가 필요한 경우 해당 상태를 var에 넣습니다.
실제 예제가 진행되는 한 수행하려는 작업의 예제를 제공하면 무엇을 사용해야하는지 알려줄 수 있습니다.
이러한 유형에 대해 처음 읽었을 때 각 유형을 사용할 수 있거나 사용해야하는 위치를 이해하는 데 어려움을 겪었으므로 여기에 내 평범한 영어 답변이 있습니다.
데이터가 변경되지 않을 때 var를 사용하십시오. 이것은 def
또는 def
같이 시작하는 대부분의 기능을 사용할 때마다 발생합니다 defn
.
변경되는 단일 항목이있을 때 원자를 사용하십시오. 항목을 추가하려는 카운터 또는 벡터를 예로들 수 있습니다.
동시에 변경해야하는 두 개 이상의 항목이있을 때 ref를 사용합니다. 익숙하다면 "데이터베이스 트랜잭션"을 생각하십시오. 이것의 표준적인 예는 한 계좌에서 다른 계좌로 돈을 이체하는 것입니다. 각 계정은 ref에 저장되어 변경 사항이 원자 적으로 표시되도록 할 수 있습니다.
무언가를 바꾸고 싶지만 언제든 상관하지 않을 때 에이전트를 사용하십시오. 이것은 긴 계산이거나 파일 또는 소켓에 무언가를 쓰는 것일 수 있습니다. 후자의 경우 send-off
.
참고 : 각각에 대해 훨씬 더 많은 내용이 있다는 점에 감사하지만 이것이 시작점을 제공 할 것입니다.
나는 그들 사이의 차이점을 요약하여 기사를 썼고 어떤 것을 사용할 때 선택할 수 있도록 도와줍니다.
공유 상태-vars, atom, agent 및 refs를 사용할 때?
그 주제에 대한 답을 찾는 사람들에게 도움이되기를 바랍니다.
@tunaci 제안 후 기사의 일부 바로 가기 :
Vars
Vars는 모든 스레드에 대해 전역 적입니다.
생성 후 변수를 변경하지 마십시오. 기술적으로 가능하지만 여러 가지 이유로 나쁜 생각입니다.
원자
모든 스레드에 대해 변경 가능한 상태에 대한 액세스를 공유합니다. 변경은 동 기적으로 발생합니다. 다른 스레드가 실행 중에 상태를 변경하면 재 시도하십시오.
장시간 실행시 멱등 함수 및 함수를 사용하지 마십시오.
자치령 대표
모든 스레드에 대해 변경 가능한 상태에 대한 액세스를 공유합니다. 변경은 비동기 적으로 발생합니다.
참조
Refs는 데이터베이스 트랜잭션과 유사하게 작동합니다. 쓰기와 읽기는 dosync에서 보호됩니다. 거래에서 안전한 많은 심판을 운영 할 수 있습니다.
일부 업데이트는 항상 가능하므로 웹 사이트의 이미지를 참조하십시오.
복사 및 과거 기사없이 전체 답변을 제공하는 것은 복잡하고 긴 주제이므로 웹 사이트로 리디렉션되는 것을 용서해주십시오 :)
원자, 심판 및 에이전트-여기에 일부 조명 http://blog.jayfields.com/2011/04/clojure-state-management.html
state-a
만하고 싶지만state-b
그렇게 할 때 참조 하는ref
경우 에도 올바른 정보 가 필요 합니까? 그래서 그것은 여러 가지를 변경하는 것이 아니라 여러 가지를 참조하면서 그중 하나를 변경하는 것입니까?