나는 요청 (즉 스레드)에서 주어진 함수가 호출 된 횟수를 추적 할 수있는 웹 응용 프로그램이 있습니다.Clojure의 Threadlocal 카운터
ref를 사용하여 비 스레드 로컬 방식으로 수행 할 수 있다는 것을 알고 있지만 어떻게 로컬에서 스레드를 수행 할 것인가?
나는 요청 (즉 스레드)에서 주어진 함수가 호출 된 횟수를 추적 할 수있는 웹 응용 프로그램이 있습니다.Clojure의 Threadlocal 카운터
ref를 사용하여 비 스레드 로컬 방식으로 수행 할 수 있다는 것을 알고 있지만 어떻게 로컬에서 스레드를 수행 할 것인가?
이 도구는 useful에 thread-local
이라고합니다. 예를 들어, (def counter (thread-local (atom 0)))
과 같이 작성할 수 있습니다. 이렇게하면 deref
이 처리 될 때 스레드 당 새 아톰을 산출하는 전역 변수가 만들어집니다. 따라서 현재 값을 @@counter
으로 읽거나 (swap! @counter inc)
으로 증가시킬 수 있습니다. 물론, @counter
을 사용하여 원자 자체를 파악한 다음 정상적인 원자처럼 취급 할 수도 있습니다.
ref31에 ThreadLocal의 인스턴스를 유지할 수 있습니다. 그리고 늘릴 필요가있을 때마다 값을 읽고 값을 높이고 다시 설정하십시오. 요청을 시작할 때 스레드가 다른 요청에 대해 재사용 될 수 있으므로 0으로 스레드 로컬을 초기화해야합니다.
binding
의 값에 바인딩 된 동적 전역 변수를 사용하여 특수 양식 set!
과 조합하여 값을 변경할 수 있습니다. binding
으로 묶인 바르는 스레드 로컬입니다. 다음은 내-FN이 with-counter
호출 내에서 호출 어떤 형태 호출됩니다 *counter*
때마다 증가 :
(def ^{:dynamic true} *counter*)
(defmacro with-counter [& body]
`(binding [*counter* 0]
[email protected]
*counter*))
(defn my-fn []
(set! *counter* (inc *counter*)))
는 설명하기 위해 시도 : 자세한 내용은
(with-counter (doall (repeatedly 5 my-fn)))
;; ==> 5
확실히 ThreadLocal에서 ref를 유지하는 것이 다른 방법보다 쉽습니다. ThreadLocal은 변경 가능하고 ref와 조화되지 않기 때문에, ref에 ThreadLocal을 유지하는 것이 합리적이지는 않습니다. 다시 시도한 트랜잭션은 어쨌든 중단됩니다. – amalloy