我在第379页的Expert F#副本中注意到以下注释:
传递和处理消息
通常在共享内存并发和消息传递并发之间进行区分。前者在本地计算机上通常更有效,本章后面的“使用共享内存并发”一节将对此进行介绍。后者适用于没有共享内存的系统,例如分布式系统,也可用于避免与共享内存相关的性能问题。
我感兴趣的是在没有共享内存的进程之间传递消息的并发性。Expert F#和互联网上演示如何使用MailboxProcessor的所有示例都包含以下代码的一些变体:
let counter =
MailboxProcessor.Start(fun inbox ->
let rec loop n =
async {
do printfn "n = %d, waiting... " n
let! msg = inbox.Receive()
match msg with
| -1 ->
do printfn "'Til the bitter end..."
return ()
| n -> return! loop(n + msg)
}
loop 0)
counter.Post(20)
counter.Post(50)
counter.Post(-1) // kill mailbox
换句话说,您必须在共享内存中拥有MailboxProcessor的句柄,然后才能将消息发布到它的通道。据我所知,这不是Erlang风格的并发,因为您只能在同一进程中将消息发送到MailboxProcessors (注意:进程,而不是线程)。
一个进程中的一个MailboxProcessor是否可以向另一个MailboxProcessor进程发送消息?如果有,你能提供一个样本吗?
发布于 2009-02-02 03:37:39
我想你对术语有点迷惑了。Erlang进程不一定直接对应于OS进程。给定的OS进程可以有多个Erlang进程(通常也是这样),就像您的进程有多个线程一样。如果您想在多个OS进程之间进行通信,您可能需要查看System.Runtime.Remoting.Channels.Ipc。可以想象,可以围绕这些API创建一个MailboxProcessor风格的包装器。
发布于 2010-07-22 03:11:27
MailboxProcessor和AsyncReplyChannel提供的位置透明度与"pid bang“(Pid !)不同。Erlang中的操作。当然,这只在分布式Erlang节点配置正确时才起作用,即名称、DNS、同步模块、cookies等。OTP中有一些功能可以简化此管理。当然,如果Erlang进程在同一个节点上,它就能正常工作。但是,分布式Erlang也有一些问题。
“网络是安全的。”内置的分布式Erlang机制假定网络是安全的。因此,当需要安全性时,使用代理Erlang进程的基于套接字的通信方法。
“网络是可靠的”。使分布式Erlang工作的一件事是它的错误处理哲学,即进程是不可靠的,因此只有通过与进程监视器通信才能实现容错。OTP将模式(即Supervisor)编成代码来实现这一理念。Erlang中的可靠消息传递可以通过Mnesia (一个分布式数据库)来实现,就像在RabbitMQ中所做的那样,但是您无法开箱即用。
最后,分布式通信永远不会这么容易。我们可以在F#中实现一个AsynchWorker来充当我们的代理,并通过AsynchReplyChannel.Send与它通信。我们仍然需要思考分布式计算的谬误。
最后,消息传递风格的并发并不意味着进程外通信。它确实意味着不需要使用锁来管理共享状态,因此是一种更简单、更不容易出错的并行计算模型。我认为这个Prime Number Sieve是这种并发风格的一个很好的例子。F#示例不像Squeak或Erlang实现那样美观,因为缺少用于消息传递的内置语法,但它可以工作。
发布于 2011-02-09 00:51:30
https://stackoverflow.com/questions/501656
复制相似问题