Я одобрил бы:
while ((c = getchar()) == ' ') /* Eat spaces */;
у меня, как также было известно, была процедура под названием DoNothing специально для вызова в случаях как это. Это делает его очень ясным, что Вы действительно означаете ничего не делать.
, В то время как несуществующие тела циклов совершенно приемлемы, должно быть ОЧЕНЬ ясно, что это является намеренным.
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.
В первом ответе была хорошая точка зрения на 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
ActorPing (лицензия Apache) от lift-util имеет расписание и scheduleAtFixedRate Источник: ActorPing.scala
Из scaladoc:
Объект ActorPing планирует, что субъект будет пинговать- ed с заданным сообщением через определенные промежутки времени. Методы расписания возвращают объект ScheduledFuture, который при необходимости можно отменить