线程化 Erlang C-Node(cnode) 互操作性如何?
我在 Erlang 开发中需要创建一个 C 节点(请参阅 C-Node 文档的链接)。基本实现很简单,但是文档中有一个巨大的漏洞。
该代码实现了单线程客户端和服务器。暂时忽略客户端...实现服务器的“c”代码是单线程的,一次只能连接到一个 erlang 客户端。
- 启动 EPMD ('epmd -daemons')
- 启动服务器应用程序 ('cserver 1234')
- 启动 erlang 客户端应用程序 ('erl -sname e1 -setcookie Secretcookie') [在与 #2 不同的窗口中]
- 执行服务器命令 (' Complex3:foo(3).') 来自 #3 中的 erlang shell
现在服务器正在运行并且当前的 erlang shell 已连接到服务器,请从另一个窗口再次尝试。
- 打开一个新窗口。
- 启动 erlang 客户端('erl -sname e2 -setcookie Secretcookie')。
- 执行新的服务器命令('complex3:foo(3).')。
请注意,系统似乎挂起......而它应该执行该命令。它挂起的原因是因为另一个 erlang 节点已连接并且没有其他线程侦听连接。
注意:连接处理中似乎存在错误。我在接收块中添加了超时,并且捕获了一些错误行为,但我没有全部捕获。另外,如果我在执行指定步骤后强制第一个 erlang 节点终止,我就能使 cserver 崩溃,而不会出现警告或错误。
所以问题是...实现线程 C 节点的最佳方法是什么?合理的连接数是多少?
I am at a point in my Erlang development where I need to create a C-Node (see link for C-Node docs). The basic implementation is simple enough, however, there is a huge hole in the doc.
The code implements a single threaded client and server. Ignoring the client for the moment... The 'c' code that implements the server is single threaded and can only connect to one erlang client at a time.
- Launch EPMD ('epmd -daemons')
- Launch the server application ('cserver 1234')
- Launch the erlang client application ('erl -sname e1 -setcookie secretcookie') [in a different window from #2]
- execute a server command ('complex3:foo(3).') from the erlang shell in #3
Now that the server is running and that a current erlang shell has connected to the server try it again from another window.
- open a new window.
- launch an erlang client ('erl -sname e2 -setcookie secretcookie').
- execute a new server command ('complex3:foo(3).').
Notice that the system seems hung... when it should have executed the command. The reason it is hung is because the other erlang node is connected and that there are no other threads listening for connections.
NOTE: there seems to be a bug in the connection handling. I added a timeout in the receive block and I caught some errant behavior but I did not get them all. Also, I was able to get the cserver to crash without warnings or errors if I forced the first erlang node to terminate after the indicated steps were performed.
So the question... What is the best way to implement a threaded C-Node? What is a reasonable number of connections?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
cnode 教程中的 cnode 实现示例并不意味着处理多个连接节点,因此,您遇到的第一个症状是正常的。
erl_accept
调用用于接受传入连接。请注意,以这种方式编写,cnode 将仅接受一个连接,然后将描述符传递给读/写循环。这就是为什么当 erlang 节点关闭时,cnode 会以错误结束,因为
erl_receive_msg
将失败,因为fd
将指向一个关闭的套接字。如果您想接受多个入站连接,则必须循环接受连接并实现一种处理多个文件描述符的方法。您不需要多线程程序来执行此操作,如果您的操作系统支持,使用 poll 或 select 系统调用可能会更容易(并且可能更有效)。
至于最佳连接数,我认为没有一个规则,如果你想在 cnode 中支持高并发,你需要对你的应用程序进行基准测试。但在这种情况下,最好重新设计系统,以便 erlang 能够处理并发性,从而减轻 cnode 的负担。
The cnode implementation example in the cnode tutorial is not meant to handle more than one connected node, so the first symptom you're experiencing is normal.
The
erl_accept
call is what accepts incoming connections.Note that, written this way, the cnode will accept only one connection and then pass the descriptor to the read/write loop. That's why when the erlang node closes, the cnode ends with an error, since
erl_receive_msg
will fail becausefd
will point to a closed socket.If you want to accept more than one inbound connection, you'll have to loop accepting connections and implement a way to handle more than one file descriptor. You needn't a multithread programme to do so, it would probably be easier (and maybe more efficient) to use the
poll
orselect
syscall if your OS supports them.As for the optimum number of connections, I don't think there is a rule for that, you'd need to benchmark your application if you want to support high concurrency in the cnode. But in that case it would probably be better to re-engineer the system so that erlang copes with the concurrency, alleviating the cnode from that.