2010-02-21 2 views
6

이 프로그램은 main()을 실행 한 후에 종료하지 않습니다.정상적인 종료 동작을 방해하지 않고 기존 프로그램에 스칼라 액터를 추가하려면 어떻게합니까?

object Main 
{ 
    def main(args: Array[String]) { 
     ... // existing code 
     f() 
     ... // existing code 
    } 
    def f() { 
     import scala.actors.Actor._ 
     val a = actor { 
      loop { 
       react { 
       case msg: String => System.out.println(msg) 
       } 
      } 
     } 
     a ! "hello world" 
    } 
} 

이러한 예기치 않은 부작용 때문에 액터를 사용하는 것이 방해가되는 것으로 볼 수 있습니다.

프로그램 종료까지 배우를 계속 실행한다고 가정 할 때 모든 종료의 경우 원래 행동을 유지하려면 어떻게해야합니까?

답변

7

2.8에는 이것을 허용하는 DaemonActor 클래스가 있습니다. 2.7.x에서는 라이브 액터가있는 경우에도 종료를 막지 않는 사용자 정의 스케줄러를 해킹 할 수 있습니다. 또는 주 끝에서 System.exit()을 호출 할 수있는 쉬운 방법을 원한다면.

액터를 경량 스레드로 생각하면 라이브 배우가 프로그램 종료를 막으려 고 할 때가 많습니다. 그렇지 않으면 액터에서 모든 작업을 수행하는 프로그램이있는 경우 모든 액터가 끝날 때까지 액티브 상태로 유지하려면 메인 스레드에 무언가를 가져야합니다.

+0

감사합니다. 내가 시도해 볼게요 2.8 베타 –

4

위 예제의 주 스레드가 완료된 후 프로그램에는 여전히 액터를 실행하는 비 데몬 스레드가 있습니다. 일반적으로 Thread.destroy() 또는 System.exit()를 사용하여 실행중인 스레드를 잔인하게 종료하는 것은 좋지 않은 생각입니다. 결과는 데이터 손상 및 교착 상태를 포함하여 프로그램에 매우 나쁜 영향을 줄 수 있습니다. 이것이 Thread.destroy()와 같은 메소드가 Java에서 처음 사용되는 이유입니다. 올바른 방법은 명시 적으로 스레드에 종료 논리를 구현하는 것입니다. 스칼라 액터의 경우, 실행중인 모든 액터에게 Stop 메시지를 보내고받을 때 종료하도록합니다. 이 방법을 사용하면 샘플은 다음과 같습니다.

object Main 
{ 
    case object Stop 
    def main(args: Array[String]) { 
     ... // existing code 
     val a = f() 
     a ! "hello world" 
     ... // existing code 
     a ! Stop 
    } 
    def f() = { 
     import scala.actors.Actor._ 
     actor { 
      loop { 
       react { 
        case msg: String => System.out.println(msg) 
        case Stop => exit() 
       } 
      } 
     } 
    } 
} 
+0

아아, 배우의 일생을 수동으로 관리하는 것은 피하고 싶었던 것입니다 ... main()을 변경해야하기 때문에 방해가됩니다. –