[clojure] Clojure 선물과 약속은 어떻게 다릅니 까?

선물과 약속은 모두 가치를 계산할 때까지 차단됩니다. 그렇다면 이들의 차이점은 무엇입니까?



답변

Clojure 용어로 대답하면 다음은 Sean Devlin의 스크린 캐스트의 몇 가지 예입니다 .

(def a-promise (promise))
(deliver a-promise :fred)

(def f (future (some-sexp)))
(deref f)

promise에서는 나중에 계산 ( :fred이 경우)에서 선택한 값을 명시 적으로 제공합니다 . 반면에 미래는 창조되었던 곳에서 소비되고 있습니다. 은 some-expr아마도 뒤에서 출시 탠덤 (결국)에서 계산하지만 시간에 의해 평가되지 않은 남아있는 경우 사용할 수있을 때까지이 스레드 블록을 액세스 할 수있다.


추가하기 위해 편집 됨

약속과 미래를 더 잘 구별하려면 다음 사항에 유의하십시오.

약속

  1. 당신은을 만들 promise. 이제 약속 객체를 모든 스레드에 전달할 수 있습니다.
  2. 계산을 계속합니다. 이는 부작용, 데이터 다운로드, 사용자 입력, 데이터베이스 액세스, 기타 약속과 관련된 매우 복잡한 계산 일 수 있습니다. 코드는 모든 프로그램의 메인 라인 코드와 매우 유사합니다.
  3. 완료되면 deliver약속 객체에 대한 결과를 얻을 수 있습니다 .
  4. deref계산이 끝나기 전에 약속 을 시도하는 모든 항목 은 완료 될 때까지 차단됩니다. 완료 deliver하고 약속을 준수하면 약속이 더 이상 차단되지 않습니다.

미래

  1. 당신은 당신의 미래를 창조합니다. 미래의 일부는 계산을위한 표현입니다.
  2. 미래는 동시에 실행될 수도 있고 실행되지 않을 수도 있습니다. 풀에서 스레드를 할당 할 수 있습니다. 기다렸다가 아무것도하지 않을 수 있습니다. 당신의 관점에서 당신은 말할 수 없습니다 .
  3. 어느 시점에서 당신 (또는 다른 스레드) deref은 미래입니다. 계산이 이미 완료된 경우 결과를 얻을 수 있습니다. 아직 완료되지 않은 경우 완료 될 때까지 차단합니다. (아마도 아직 시작되지 않았다면 deref실행이 시작되었음을 의미하지만 이것도 보장되지는 않습니다.)

Promise 생성 이후의 코드만큼 복잡하게 표현할 있지만 , 그것이 바람직한지는 의심 스럽습니다. 즉, 미래는 빠르고 배경이 가능한 계산에 더 적합하고 약속은 크고 복잡한 실행 경로에 더 적합합니다. 또한 사용 가능한 계산 측면에서 약속은 작업을 수행하는 약속 생성자와 수확을 거두는 또 다른 스레드에 대해 조금 더 유연하고 지향적 인 것처럼 보입니다. 퓨처는 스레드를 자동으로 시작하고 (추악하고 오류가 발생하기 쉬운 오버 헤드없이) 원래 스레드가 결과를 필요로 할 때까지 다른 작업을 계속하는 방향으로 향합니다.


답변

Future와 Promise는 모두 생산자에서 소비자에게 비동기 계산의 결과를 전달하는 메커니즘 입니다. Future

경우 계산 은 Future 생성시 정의되고 비동기 실행은 “ASAP”시작됩니다. 또한 비동기 계산을 생성하는 방법을 “알고”있습니다.
경우 약속 계산 , 그 개시 시간 및 [수] 비동기 호출이 전달기구로부터 분리된다. 경우 연산 결과 가능 프로듀서 호출해야 또한 생산자 제어 의미 명시 결과가 가능해진다.

deliver

들어 약속 Clojure의 동일한 오브젝트 (의 결과를 사용하여 설계 실수를 promise모두 생산 (에 호출) deliver) 및 소비 ( deref)의 결과를 계산 . 이는 매우 뚜렷한 두 가지 기능이므로 그렇게 취급해야합니다.


답변

이미 훌륭한 답변이 있으므로 “사용 방법”요약 만 추가하면됩니다.

양자 모두

promise 또는 future를 생성하면 즉시 참조가 반환됩니다. 이 참조는 다른 스레드에서 계산 결과를 제공 할 때까지 @ / deref에서 차단됩니다.

미래

미래를 만들 때 수행 할 동기 작업을 제공합니다. 제한되지 않은 전용 풀의 스레드에서 실행됩니다.

약속

약속을 만들 때 아무런 주장도하지 않습니다. 참조는 deliver결과 가 될 다른 ‘사용자’스레드로 전달되어야합니다 .


답변

Clojure의에서 promise, future그리고 delay약속과 같은 개체입니다. 이들은 모두 클라이언트가 deref(또는 @) 을 사용하여 기다릴 수있는 계산을 나타냅니다 . 클라이언트는 결과를 재사용하므로 계산이 여러 번 실행되지 않습니다.

계산이 수행되는 방식이 다릅니다.

  • future다른 작업자 스레드에서 계산을 시작합니다. deref결과가 준비 될 때까지 차단됩니다.

  • delay첫 번째 클라이언트가 deref, 또는을 사용할 때 계산을 느리게 수행합니다 force.

  • promise를 사용하여 사용자 지정 방식으로 결과를 제공하므로 가장 큰 유연성을 제공합니다 deliver. 둘 다 사용하지 future않거나 delay사용 사례와 일치 할 때 사용합니다 .


답변

첫째, a PromiseFuture. 나는 당신이 a Promise와 a 의 차이점을 알고 싶다고 생각합니다 FutureTask.

A Future는 현재 알려지지 않았지만 앞으로 알려질 값을 나타냅니다.

A FutureTask는 미래에 발생할 계산의 결과를 나타냅니다 (일부 스레드 풀에서). 결과에 액세스하려고 할 때 계산이 아직 발생하지 않으면 차단됩니다. 그렇지 않으면 결과가 즉시 반환됩니다. 계산은 귀하가 미리 지정하므로 결과 계산에 관여하는 다른 당사자가 없습니다.

A Promise는 약속자가 향후 약속 자에게 전달할 결과를 나타냅니다. 이 경우에 당신은 약속 자이고 약속자는 당신에게 Promise물건 을 준 사람 입니다. 와 유사하게 FutureTask,가 처리되기 전에 결과에 액세스하려고 Promise하면 약속자가 Promise. 일단 Promise충족 되면 항상 동일한 가치를 얻습니다. 와 달리 FutureTask여기에 다른 당사자가 참여하여 Promise. 다른 당사자는 계산을 수행하고 Promise.

그런 의미에서 a FutureTaskPromise당신이 만든 것입니다.


답변