Scala演员:接收与反应 [英] Scala actors: receive vs react

查看:102
本文介绍了Scala演员:接收与反应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先让我说我有很多Java经验,但是直到最近才对函数式语言感兴趣.最近,我开始研究Scala,这似乎是一种非常不错的语言.

Let me first say that I have quite a lot of Java experience, but have only recently become interested in functional languages. Recently I've started looking at Scala, which seems like a very nice language.

但是,我已经在 在Scala中编程中了解了Scala的Actor框架. ,有一件事我不明白.在第30.4章中,它说使用react代替receive使得可以重用线程,这对性能有好处,因为JVM中的线程很昂贵.

However, I've been reading about Scala's Actor framework in Programming in Scala, and there's one thing I don't understand. In chapter 30.4 it says that using react instead of receive makes it possible to re-use threads, which is good for performance, since threads are expensive in the JVM.

这是否意味着,只要我记得叫react而不是receive,我就可以启动任意数量的Actor?在发现Scala之前,我一直在与Erlang一起玩,并且是 Programming Erlang的作者 引以为豪的是,它产生了超过200,000个进程.我不愿意用Java线程来做到这一点.与Erlang(和Java)相比,我在Scala中看到的限制是什么?

Does this mean that, as long as I remember to call react instead of receive, I can start as many Actors as I like? Before discovering Scala, I've been playing with Erlang, and the author of Programming Erlang boasts about spawning over 200,000 processes without breaking a sweat. I'd hate to do that with Java threads. What kind of limits am I looking at in Scala as compared to Erlang (and Java)?

此外,该线程如何在Scala中重复使用?为了简单起见,我们假设我只有一个线程.我开始的所有参与者都将在此线程中按顺序运行,还是会进行某种任务切换?例如,如果我启动两个彼此进行乒乓球消息的演员,那么如果他们在同一线程中开始,我会冒死锁的风险吗?

Also, how does this thread re-use work in Scala? Let's assume, for simplicity, that I have only one thread. Will all the actors that I start run sequentially in this thread, or will some sort of task-switching take place? For example, if I start two actors that ping-pong messages to each other, will I risk deadlock if they're started in the same thread?

根据 Scala编程,编写演员以使用react比使用receive困难.这听起来很合理,因为react不返回.但是,本书继续说明如何使用Actor.loopreact放入循环中.结果,您得到

According to Programming in Scala, writing actors to use react is more difficult than with receive. This sounds plausible, since react doesn't return. However, the book goes on to show how you can put a react inside a loop using Actor.loop. As a result, you get

loop {
    react {
        ...
    }
}

在我看来,这很像

while (true) {
    receive {
        ...
    }
}

在本书前面使用.本书仍然指出,实际上,程序至少需要几个receive".那我在这里想念什么?除了返回,receive还能做什么?而我为什么要在意呢?

which is used earlier in the book. Still, the book says that "in practice, programs will need at least a few receive's". So what am I missing here? What can receive do that react cannot, besides return? And why do I care?

最后,进入我不了解的核心内容:这本书不断提到使用react如何使丢弃调用堆栈以重新使用线程成为可能.这是如何运作的?为什么有必要放弃调用堆栈?以及为什么当函数通过引发异常(react)终止而不能通过返回(receive)终止而不能丢弃调用堆栈?

Finally, coming to the core of what I don't understand: the book keeps mentioning how using react makes it possible to discard the call stack to re-use the thread. How does that work? Why is it necessary to discard the call stack? And why can the call stack be discarded when a function terminates by throwing an exception (react), but not when it terminates by returning (receive)?

我的印象是, Scala编程已经掩盖了这里的一些关键问题,这真是令人遗憾,因为否则它是一本真正优秀的书.

I have the impression that Programming in Scala has been glossing over some of the key issues here, which is a shame, because otherwise it's a truly excellent book.

推荐答案

首先,每个在receive上等待的actor都占用一个线程.如果它什么也没收到,那么该线程将永远不会做任何事情. react上的actor直到接收到某些东西,才占用任何线程.一旦收到东西,就会为它分配一个线程,并在其中对其进行初始化.

First, each actor waiting on receive is occupying a thread. If it never receives anything, that thread will never do anything. An actor on react does not occupy any thread until it receives something. Once it receives something, a thread gets allocated to it, and it is initialized in it.

现在,初始化部分很重要.预期接收线程将返回某些内容,而反应线程则不会.因此,最后一个react末尾的先前堆栈状态可以被完全丢弃.不需要保存或恢复堆栈状态,可以使线程启动更快.

Now, the initialization part is important. A receiving thread is expected to return something, a reacting thread is not. So the previous stack state at the end of the last react can be, and is, wholly discarded. Not needing to either save or restore the stack state makes the thread faster to start.

出于各种性能原因,您可能想要一个或另一个.如您所知,在Java中拥有太多线程不是一个好主意.另一方面,因为必须先将actor附加到线程上,然后它才能react,所以对receive消息的消息要比对react的消息更快.因此,如果您的演员接收到很多消息,但是却很少处理,那么react的额外延迟可能会使它太慢而无法满足您的目的.

There are various performance reasons why you might want one or other. As you know, having too many threads in Java is not a good idea. On the other hand, because you have to attach an actor to a thread before it can react, it is faster to receive a message than react to it. So if you have actors that receive many messages but do very little with it, the additional delay of react might make it too slow for your purposes.

这篇关于Scala演员:接收与反应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆