2011-09-12 4 views
4

나는 요청 (즉 스레드)에서 주어진 함수가 호출 된 횟수를 추적 할 수있는 웹 응용 프로그램이 있습니다.Clojure의 Threadlocal 카운터

ref를 사용하여 비 스레드 로컬 방식으로 수행 할 수 있다는 것을 알고 있지만 어떻게 로컬에서 스레드를 수행 할 것인가?

답변

10

이 도구는 usefulthread-local이라고합니다. 예를 들어, (def counter (thread-local (atom 0)))과 같이 작성할 수 있습니다. 이렇게하면 deref이 처리 될 때 스레드 당 새 아톰을 산출하는 전역 변수가 만들어집니다. 따라서 현재 값을 @@counter으로 읽거나 (swap! @counter inc)으로 증가시킬 수 있습니다. 물론, @counter을 사용하여 원자 자체를 파악한 다음 정상적인 원자처럼 취급 할 수도 있습니다.

-1

ref31에 ThreadLocal의 인스턴스를 유지할 수 있습니다. 그리고 늘릴 필요가있을 때마다 값을 읽고 값을 높이고 다시 설정하십시오. 요청을 시작할 때 스레드가 다른 요청에 대해 재사용 될 수 있으므로 0으로 스레드 로컬을 초기화해야합니다.

+2

확실히 ThreadLocal에서 ref를 유지하는 것이 다른 방법보다 쉽습니다. ThreadLocal은 변경 가능하고 ref와 조화되지 않기 때문에, ref에 ThreadLocal을 유지하는 것이 합리적이지는 않습니다. 다시 시도한 트랜잭션은 어쨌든 중단됩니다. – amalloy

7

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 

참조 http://clojure.org/vars#set