Как я могу добавить scala агентов к существующей программе, не вмешиваясь в нормальное поведение завершения?

Эта программа, после выполнения основного (), не выходит.

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"
    }
}

Из-за этого неожиданного побочного эффекта, с помощью агентов может быть просмотрен как навязчивый.

Принятие агентов должно продолжить работать до завершения программы, как Вы сделали бы для сохранения исходного поведения во всех случаях завершения?

6
задан Eldritch Conundrum 21 February 2010 в 11:44
поделиться

2 ответа

В 2.8 есть класс DaemonActor, который позволяет это сделать. В 2.7.x вы можете встроить собственный планировщик, который не предотвращает выключение, даже если все еще есть живые акторы, или, если вы хотите простой способ, вы можете вызвать System.exit() в конце main.

Если вы рассматриваете актор как нечто вроде легковесного потока, то в большинстве случаев вам нужен живой актор, чтобы предотвратить завершение программы. В противном случае, если у вас есть программа, которая выполняет всю свою работу в акторах, вам потребуется что-то на главном потоке, чтобы он оставался живым, пока все акторы не закончат свою работу.

7
ответ дан 9 December 2019 в 22:33
поделиться

После завершения основного потока в приведенном выше примере в программе все еще оставался недемонский поток, запускающий актера. Обычно это плохая идея - грубо завершать запущенные потоки с помощью Thread.destroy() или System.exit(), поскольку результаты могут быть очень плохими для вашей программы, включая, но не ограничиваясь, повреждение данных и тупики. Именно поэтому Thread.destroy() и аналогичные методы были в первую очередь устаревшими в Java. Правильным способом будет явная реализация логики завершения в ваших потоках. В случае с акторами Scala это сводится к отправке сообщения 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()
                }
            }
        }
    }
}
4
ответ дан 9 December 2019 в 22:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: