Агенты сна?

Я одобрил бы:

while ((c = getchar()) == ' ') /* Eat spaces */;

у меня, как также было известно, была процедура под названием DoNothing специально для вызова в случаях как это. Это делает его очень ясным, что Вы действительно означаете ничего не делать.

, В то время как несуществующие тела циклов совершенно приемлемы, должно быть ОЧЕНЬ ясно, что это является намеренным.

16
задан Joe 3 August 2009 в 20:05
поделиться

3 ответа

There's no need to explicitly cause an actor to sleep: using loop and react for each actor means that the underlying thread pool will have waiting threads whilst there are no messages for the actors to process.

In the case that you want to schedule events for your actors to process, this is pretty easy using a single-threaded scheduler from the java.util.concurrent utilities:

object Scheduler {
  import java.util.concurrent.Executors
  import scala.compat.Platform
  import java.util.concurrent.TimeUnit
  private lazy val sched = Executors.newSingleThreadScheduledExecutor();
  def schedule(f: => Unit, time: Long) {
    sched.schedule(new Runnable {
      def run = f
    }, time , TimeUnit.MILLISECONDS);
  }
}

You could extend this to take periodic tasks and it might be used thus:

val execTime = //...  
Scheduler.schedule( { Actor.actor { target ! message }; () }, execTime)

Your target actor will then simply need to implement an appropriate react loop to process the given message. There is no need for you to have any actor sleep.

17
ответ дан 30 November 2019 в 16:05
поделиться

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

import actors.{Actor,TIMEOUT}

def scheduler(time: Long)(f: => Unit) = {
  def fixedRateLoop {
    Actor.reactWithin(time) {
      case TIMEOUT => f; fixedRateLoop
      case 'stop => 
    }
  }
  Actor.actor(fixedRateLoop)
}

И давайте протестируем его (я сделал это прямо в Scala REPL) с помощью тестового клиентского актора:

case class Ping(t: Long)

import Actor._
val test = actor { loop {
  receiveWithin(3000) {
    case Ping(t) => println(t/1000)
    case TIMEOUT => println("TIMEOUT")
    case 'stop => exit
  }
} }

Запустите планировщик:

import compat.Platform.currentTime
val sched = scheduler(2000) { test ! Ping(currentTime) }

, и вы увидите что-то вроде этого

scala> 1249383399
1249383401
1249383403
1249383405
1249383407

, что означает, что наш планировщик отправляет сообщение каждые 2 секунды, как и ожидалось. Остановим планировщик:

sched ! 'stop

тестовый клиент начнет сообщать о тайм-аутах:

scala> TIMEOUT
TIMEOUT
TIMEOUT

остановите его также:

test ! 'stop
21
ответ дан 30 November 2019 в 16:05
поделиться

ActorPing (лицензия Apache) от lift-util имеет расписание и scheduleAtFixedRate Источник: ActorPing.scala

Из scaladoc:

Объект ActorPing планирует, что субъект будет пинговать- ed с заданным сообщением через определенные промежутки времени. Методы расписания возвращают объект ScheduledFuture, который при необходимости можно отменить

4
ответ дан 30 November 2019 в 16:05
поделиться
Другие вопросы по тегам:

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