4

그래서 stackoverflow에 대한 질문은 한 가지 방법 또는 다른 방법으로 미래를 "죽이는"방법을 묻는 것입니다 (비추천 Thread.stop()). 나는 그것이 불가능한 이유를 설명하는 대답을 보지만 유사한 문제를 해결할 수있는 대안은 아닙니다. 예를 들어다중 스레드 스칼라의 긴 프로세스에 대한 관용적 인 시간 초과

". 살해"나는 미래가 될 수 없다 실현 Practical use of futures? Ie, how to kill them?

내가 어떻게 이런 방식으로 Java를 수행 할 수 있는지 알았습니다. 태스크를 더 작은 수면 상태로 분해하고 주기적으로 검사되는 스레드 클래스에서 "휘발성 부울 isStillRunning"을 사용하십시오. 이 값을 업데이트하여 스레드를 취소 한 경우 스레드가 종료됩니다. 여기에는 "공유 상태"(isStillRunning var)가 포함됩니다. 스칼라에서 동일한 작업을 수행하는 경우 매우 기능적으로 보이지 않습니다.

관용적 기능 스칼라에서 이런 종류의 문제를 해결하는 올바른 방법은 무엇입니까? 그것을하는 합리적으로 간결한 방법 있는가? "정상적인"스레딩 및 휘발성 플래그로 되돌려 야합니까? Java 키워드와 같은 방식으로 @volatile를 사용해야합니까?

답변

1

나는 내 자신의 문제에 대한 더 나은 해결책을 찾았다 고 생각합니다. 운영체제가 언제 죽을지 알 수 있도록 휘발성 변수를 사용하는 대신 우선 순위가 더 높은 종료 메시지를 액터로 보낼 수 있습니다. ..

val a = new Actor() { 
    def act():Unit = { 
    loop{ react { 
     case "Exit" => exit(); return; 
     case MyMessage => { 
     //this check makes "Exit" a high priority message, if "Exit" 
     //is on the queue, it will be handled before proceeding to 
     //handle the real message. 
     receiveWithin(0) { 
      case "Exit" => exit(); return 
      case TIMEOUT => //don't do anything. 
     } 
     sender ! "hi!" //reply to sender 
     } 
    }} 
    } 
} 

a.start() 
val f = a !! MyMessage 
while(! f.isSet && a.getState != Actor.State.Terminated) { 
    //will probably return almost immediately unless the Actor was terminated 
    //after I checked. 
    Futures.awaitAll(100,f) 
} 
if(a.getState != Actor.State.Terminated) { 
    f() // the future should evaluate to "hi!" 
} 
a ! "Exit" //stops the actor from processing anymore messages. 
      //regardless of if any are still on the queue. 
a.getState // terminated 

아마이 작성하는 청소기 방법이있다하지만 내 응용 프로그램에서 무슨 짓을했는지 약 : 그것은이 같은 것을 보인다.

대기열에 "Exit"메시지가 없으면 reactWithin (0)은 즉시 no-op입니다. queue'd "Exit"메시지는 스레드 된 Java 응용 프로그램에 있던 휘발성 부울을 대체합니다.

+0

글쎄, 나는 미래를 언급했으나 질문의 ​​제목은 "멀티 스레드 스칼라에서 긴 프로세스에 대한 관용적 인 타임 아웃"입니다. 문제의 종류에 대한 관용적 인 해결책을 찾고있었습니다. 반드시 미래 나 배우가 아닙니다. 당신은 솔루션이 "자바에서와 똑같이 보일 것"이라고 말했지만, 그 문제를 해결할 수있는 완전한 관용적 인 방법을 보여주었습니다. Akka의 블로그는 모든 작업이 끝난 후 배우가 계속 종료되도록하는 것에 관한 것이 었습니다. 배우가 아직 진행중인 작업을 중지 할 방법을 찾고있었습니다. 스칼라와 동일합니다. http://stackoverflow.com/a/3194586/ 621233 – Brian

+0

btw ... Akka에서 이것을 수행하는 방법을 알고 싶습니다 ... 이것은 오래된 스칼라 배우 였고 스칼라 2.10으로 포팅하는 방법을 알 수없는 코드가 있습니다. – Brian

1

예, Java에서와 같습니다.

테스트 장비가 멈추거나 너무 오래 실행되는 테스트 장비의 경우, 어떤 이유로 든 테스트 실패로 약속을 사용합니다. 예를 들어 타임 아웃 모니터는 테스트 러너를 "취소"(스레드를 중단하고 플래그를 compareAndSet) 한 다음 실패한 약속을 완료 할 수 있습니다. 또는 테스트 준비가 잘못 구성된 테스트를 일찍 실패 할 수 있습니다. 또는 테스트가 실행되어 결과가 생성됩니다. 높은 수준에서 테스트 장비는 미래와 그 가치를 볼 수 있습니다.

Java와 다른 점은 선물 구성 옵션입니다.

val all = Future.traverse(tests)(test => { 
    val toKeep = promise[Result] // promise to keep, or fail by monitor 
    val f = for (w <- feed(prepare(test, toKeep))) yield { 
    monitored(w, toKeep) { 
     listener.start(w) 
     w.runTest() 
    } 
    } 
    f completing consume _ 
    // strip context 
    val g = f map (r => r.copy(context = null)) 
    (toKeep completeWith g).future 
}) 
관련 문제