当前位置: 首页 > 知识库问答 >
问题:

仅使用Akka actors作为邮箱的死锁

长孙弘壮
2023-03-14

我只想使用Akka演员作为邮箱,即我想创建n个线程,每个线程创建1个远程演员。

每个线程都获得对其他线程的所有远程参与者的引用,这样它们就可以通过各自的参与者向彼此发送消息。

参与者定义如下:

case class Receive
case class GroupReceive(id: Symbol)
case class GroupMsg[T](id: Symbol, msg: T)
class FooParActor(val distributor: Distributor) extends Actor
  with Stash {
  import context._

  val globalRank: Int = distributor.globalRank

  def doReceive(realSender: ActorRef, ID: Symbol) {
    unstashAll()
    become({
      case GroupMsg(ID, msg) =>
        realSender ! msg
        unbecome()
      case GroupMsg(otherId, msg) =>
        println(globalRank + ": stashing " + otherId)
        unbecome()
      case x => sys.error("bad msg: " + x)
    }, discardOld = false)
  }

  def receive = {
    case GroupReceive(id) =>
      doReceive(sender, id)
    case GroupMsg(id, x) =>
      stash()
    case x => sys.error("bad msg: " + x)
  }

}
def groupRcv[T](id:Symbol) = Await.result(aref ? GroupReceive(id), timeout.duration).asInstanceOf[T]

其中aref是对该线程的本地参与者的引用。

我有时会遇到上述模式的死锁(超时5秒),即使使用非常简单的方法和很小的消息也是如此。我将问题缩小到actors在收到groupreceive(id)消息后,但在输入doReceive(...)的第一个大小写之前停顿:case GroupMsg(id,msg)=>

我做了打印输出跟踪,以检查演员在执行doReceive调用之前是否确实有消息,似乎出于某种原因,他们只是不处理这些消息。上面给出的代码可以进入groupmsg()fooparactor的stash中丢失的状态吗?或者,在接收到groupreceive()消息后,参与者是否有其他方法进入死锁?

共有1个答案

伏业
2023-03-14

您正在使用await.result(),但没有共享您在哪里执行:如果您在参与者应该运行的线程上调用grouprcv,那么您当然会出现饥饿(即目标参与者没有可运行的线程,因此它永远不会完成请求)。

您似乎以一种不健康的方式将基于线程的并发与actors混合在一起,但由于您只是暗示它而不显示代码,所以我只能给您一个宽泛的建议,不要这样做。当编程演员时,忘记线程;那些是由Akka管理的。特别是不要滥用Akka的线程(例如,wauit.result可能在您自己的外部线程池中工作,尽管几乎总有更好的替代方案)。

最后,如果您使用actors只是为了创建“一个带有邮箱的线程”,那么Akka就帮不了您,您将遇到所有常见的传统并发陷阱。

 类似资料:
  • 本文向大家介绍python3使用QQ邮箱发送邮件,包括了python3使用QQ邮箱发送邮件的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了python3使用QQ邮箱发邮件的具体代码,供大家参考,具体内容如下 直接上代码 如果登录失败可能是你的qq邮箱没有启动SMTP 解决: 启动后QQ会提供授权码,将代码中密码改为授权码即可。 成功后: 以上就是本文的全部内容,希望对大家的学习有所帮

  • 一个线程往邮箱中发送邮件,另外一个线程往邮箱中收取邮件 一个线程往邮箱中发送邮件,另外一个线程往邮箱中收取邮件 源码/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-0

  • 邮箱接口 结构体 struct   rt_mailbox   邮箱控制块 更多...   类型定义 typedef struct rt_mailbox *  rt_mailbox_t   邮箱类型指针定义   函数 rt_err_t  rt_mb_init (rt_mailbox_t mb, const char *name, void *msgpool, rt_size_t size, rt_u

  • 一个Akka Mailbox保存发往某个Actor的消息。通常每个Actor都拥有自己的邮箱,但也有例外,例如使用BalancingPool的所有路由子(routee)共享同一个邮箱实例。 邮箱选择 为actor指定一个消息队列类型 为某个特定类型的actor指定一个特定类型的消息队列是有可能的,只要通过actor扩展RequiresMessageQueue参数化特质即可。下面是一个示例: imp

  • 本文向大家介绍python实现QQ邮箱/163邮箱的邮件发送,包括了python实现QQ邮箱/163邮箱的邮件发送的使用技巧和注意事项,需要的朋友参考一下 QQ邮箱/163邮箱的邮件发送:py文件发送邮件内容相当于一个第三方的客户端,借助于QQ/163邮箱服务器来发送的邮件。 主要配置: 导入模块——import    smtplib 邮箱SMTP服务器的主机地址,HOST——将来使用这个服务器收

  • 本文向大家介绍Python使用QQ邮箱发送邮件实例与QQ邮箱设置详解,包括了Python使用QQ邮箱发送邮件实例与QQ邮箱设置详解的使用技巧和注意事项,需要的朋友参考一下 直接上代码实例:  QQ邮箱设置 更多关于Python使用QQ邮箱发送邮件的实例请查看下面的相关链接