简单的,或快速解答您的问题(S)是:
这很好,但除了一张地图,你也可以使用gb_trees,字典或ETS表(地图是当然最不成熟的)。但是,尽管如此,PID查找表的关键/ ID原则上是好的。 ETS可能会带来比其他过程更好的性能优势,因为您可以创建可从其他过程访问的ETS表,从而消除了单个过程执行所有读写操作的必要性。这可能或可能不重要和/或适当。
一个简单的方法就是每次启动一个“主代理”时,它会产生另一个进程,除了链接到“主代理”并将主代号从任何存储中删除当“主机代理”死亡时。另一种方法是使映射存储过程本身链接到您的主机代理程序PID,这可能会减少您对可能的竞争条件的关注。
可能。当我读到你的问题时,我留下了一些问题和一般感觉,我会选择的解决方案不会导致我所查询的确切查询问题(即在收到以下内容时查找“主代理”的PID)一个TCP数据包),但我不能确定这不是因为你已经努力最大限度地减少堆栈溢出的问题。对于我来说,“主机”,“主机代理”和“连接”过程的角色,责任和相互作用究竟是什么,以及它们是否应该全部存在和/或是否具有单独的监督树,有点不清楚。
所以,看可能的选择。当你说“当一个TCP数据包到达”我想,当一个国外主机连接到监听套接字或发送已经接受现有的插座上的一些数据,你的意思是,并且主机ID是主机名(或端口),或者是外部主机在连接后发送给您的任意其他ID。
无论哪种方式...通常在这种情况下,我期望一个新的进程(通过它的声音的“主机代理”)将被派生来处理新建立的TCP连接(通过一个动态的(例如简单的一对一的管理者),获得作为该连接的服务器端端点的套接字的所有权;根据需要读取和写入套接字,并在连接关闭时终止。
使用该模型时,如果已经建立连接,则始终应启动“主代理”,并且如果没有连接,则始终不启动,并且任何传入的TCP数据包将自动终止于正确的代理,因为它将被传递到代理正在处理的套接字,或者如果它是新连接,代理将启动。
现在从不会出现在收到TCP数据包时查找代理的PID的需要。
如果因为其他原因需要查找代理的PID,因为说服务器有时需要主动向可能连接的“主机”发送数据,那么您必须获取所有监督的列表“主持人代理人”并挑选出正确的人(为此,你可以使用主管:which_children/1,根据Hamidreza的回答)或者你可以使用map,gb_trees,dict,ets等来维护主机ID到PID的映射。这是正确的取决于你可以拥有多少“主机” - 如果它不止一个,那么你应该保留一个某种类型的地图,以便查找时间不会变得太大。
最后的评论,如果你还没有,可以考虑看gproc
,以防你认为它适合你的情况。它做这种事情。
编辑/添加(以下问题编辑):
你的连接过程听起来多余的给我;如上所述,如果您将套接字指定给主机代理,那么连接的大部分责任都将消失。主机代理没有理由不能解析它接收到的数据,就我所见,让另一个进程解析它并没有任何价值,只是将它传递给另一个进程。解析本身可能是一个确定性函数,所以对它有一个单独的模块是明智的,但我认为在单独的过程中没有意义。
我没有看到你的'主机'进程的重点,你说“主机保留主机信息”,这听起来像它只是一个持有主机名或主机ID的过程,类似的东西?
你也说“它指定了源主机和目标主机,这意味着它由源主机发送,应该由目标主机接收”,它开始使这个声音有点像聊天服务器,或者至少某种hub spoke/star network风格的通信协议。我不明白为什么你不能做你想要的一切,通过创建监督树这样会:
top_sup
|
.------------------------------.
| | |
map_server svc_listener hosts_sup (simple one to one)
|
.----------------------------->
| | | | | |
这里的“map_server”只是维持映射主机ID到hosts
PID的一个时, svc_listener
具有监听套接字,并且只接受连接并要求hosts_sup
在新客户端连接时产生新的host
,并且host
进程(在hosts_sup
之下)负责接受的套接字,并将主机ID及其PID注册为map_server
他们开始。
如果map_server
链接到host
的PID它能自动清理时host
死亡,并且它可以用于任何过程由主机ID来查找一个host
PID提供一个合适的API。
特定于我的使用案例,我需要检查所有连接上的所有host_agent_sup以查找是否存在相对的主机代理。这似乎有点复杂。有没有更好的解决方案来解决这种情况? – gy8409
@ gy8409同样使用地图来追踪复杂场景中的特殊过程并不是一个坏习惯。这张地图可以位于协调员进程或ets表的状态中。 –