如何忽略erlang中的超时?

时间:2014-05-12 14:12:44

标签: erlang deadlock

我有一个拥有多个客户端的服务器,每个客户端都可以向服务器询问有关其他客户端的信息。如果他们这样做,服务器必须从每个客户端获取信息,然后将其返回给提问客户端。

如果两个客户端同时执行此请求,则可能会出现死锁。问题是这个请求经常被完成,以至于客户端有时候不会关心它是否会失败。当出现此问题时,如何忽略终止所有内容的超时消息?

1 个答案:

答案 0 :(得分:1)

严格回答您的问题

如果您正在使用gen_server,则call/3允许您指定超时(并且call/2默认为5秒)。

如果失败,此代码将为您提供gen_server的回复或原子timeout

Result = try gen_server:call(Target, Message, Timeout) of
             Reply ->
                 Reply
         catch
             exit:{timeout, _} ->
                 timeout
         end.

更好的回答

推荐使用异步调用evnu和rvirding,这是一种优秀的技术。以下是两种可能的方法:

1。服务器存储数据

让客户定期gen_server:cast/2向服务器告知其信息。服务器存储有关每个客户端的最新信息。当客户想要了解其兄弟姐妹时,它会向服务器调用gen_server:call/2

服务器调用是同步的,因为它不需要联系任何客户端;它只是返回缓存的值。

2。异步返回

客户端呼叫gen_server:cast/2以从服务器请求数据。服务器调用gen_server:call/2以按需从每个客户端获取数据。一旦服务器收集了所有数据,它就会调用gen_server:cast/2将收集的数据传回给请求它的客户端。

此处,客户端始终在等待处理来自服务器的请求。服务器同步调用客户端,但由于只有一台服务器,因此无法解锁。

3。更多gen_servers

在不了解您的代码的情况下很难描述,但您可以将客户分成更多部分。一件用于处理数据请求,另一件用于生成请求。


根据您的描述,客户提出此数据请求"经常",我认为您应该尝试第一种方法。如果您的客户经常请求数据,那么让服务器收集并缓存客户端信息实际上会为客户端提供更新的数据。