与线程相比, Actors 的工作方式是否有任何好的和简短的解释?
是否可以将线程视为actor并将消息发送到其他线程?我看到了一些不同,但对我来说并不是那么清楚。我可以通过不同的方式使用任何语言的 Actors 吗?
答案 0 :(得分:74)
actor模型对消息传递进行操作。允许各个进程(参与者)彼此异步发送消息。这与我们通常认为的线程模型的区别在于(理论上至少)没有共享状态。如果一个人认为(有理由,我认为)共享国家是所有邪恶的根源,那么演员模型就会变得非常有吸引力。
但是,我们不应该过度兴奋。演员模型没有(与某些指控相反)使得无法陷入僵局。 actor模型也不会阻止您在不同进程(例如,消息队列)之间争用资源。该模型仅在某个级别之上“无锁”。在较低级别,为了协调消息队列,仍然需要锁定。线程不能被视为演员并将消息发送给其他线程吗?
嗯,是的,不是。不,如果您只是使用将互斥锁放在共享内存位置的方法。然后线程共享这个状态 - 它们都可以访问这个内存,可以读取它,重新编写它等等。但是你可以在一个线程模型之上构建一个actor模型,事实上所有的actor实现都有线程下。我通过给每个线程一个由互斥锁保护的队列来攻击这样的东西(非常糟糕) - 只是为了好玩。要了解演员线程阻抗的管理方式,请参阅my question from a year ago。
我可以通过不同的线程使用任何语言的Actor模型吗?
是的,但这需要更多的工作。您最喜欢的语言可能有一个消息传递库,因此这是首先要调查的内容。此外,您应该研究不可变数据结构的使用。请注意,如果数据结构是不可变的,那么您基本上处理了“共享状态”问题 - 多个线程可以保存对不可变数据的引用,而不会发生任何不良事件。演员语言往往也是函数式语言(erlang,scala)是有原因的。
您可能还想看一下软件事务内存,它是一个不同但又引人注目的模型。 Clojure是我最喜欢的例子。
答案 1 :(得分:2)
我不会说演员总是异步传递消息 - 这太慢了。例如,JActor项目使用双向消息(请求/响应)来更好地建模方法调用。并且大多数请求都是同步服务的。
JActor(Java库)也不使用锁。只有一些原子和并发数据结构,只有几个信号量输入。消息传递大约是每秒0.8亿条消息。