代码之家  ›  专栏  ›  技术社区  ›  Richard

线程化erlang C节点(c node)互操作性如何?

  •  3
  • Richard  · 技术社区  · 14 年前

    我在Erlang开发中的某个阶段需要创建一个C节点(请参见 link 对于C节点文档)。基本的实现非常简单,但是文档中有一个巨大的漏洞。

    代码实现了单线程客户机和服务器。暂时忽略客户端…实现服务器的“c”代码是单线程的,一次只能连接到一个Erlang客户机。

    1. 启动epmd(“epmd-守护进程”)
    2. 启动服务器应用程序(“csserver 1234”)
    3. 在与2不同的窗口中启动Erlang客户机应用程序(“erl-sname e1-setcookie secretcookie”)。
    4. 从3中的erlang shell执行服务器命令(“complex3:foo(3)”)。

    既然服务器正在运行,并且当前的erlang shell已连接到服务器,请从另一个窗口重试。

    1. 打开一个新窗口。
    2. 启动Erlang客户端(“erl-sname e2-setcookie secretcookie”)。
    3. 执行新的服务器命令(“complex3:foo(3)”)。

    注意系统似乎挂起了…它应该执行命令的时间。挂起它的原因是因为另一个erlang节点已连接,并且没有其他线程在侦听连接。

    注: 连接处理中似乎有一个错误。我在接收块中添加了一个超时,捕获了一些错误行为,但并没有全部得到。此外,如果在执行指定的步骤后强制第一个erlang节点终止,我可以让CServer崩溃,而不会出现警告或错误。

    所以问题是…实现线程化C节点的最佳方法是什么?合理的连接数量是多少?

    1 回复  |  直到 14 年前
        1
  •  3
  •   Samuel Rivas    14 年前

    中的cnode实现示例 cnode tutorial 不是为了处理多个连接的节点,因此您遇到的第一个症状是正常的。

    这个 erl_accept 呼叫是接受传入连接的方式。

    if ((fd = erl_accept(listen, &conn)) == ERL_ERROR)
      erl_err_quit("erl_accept");
    fprintf(stderr, "Connected to %s\n\r", conn.nodename);
    while (loop) {
      got = erl_receive_msg(fd, buf, BUFSIZE, &emsg);
    

    注意,这样写的话,cnode只接受一个连接,然后将描述符传递给读/写循环。这就是为什么当erlang节点关闭时,cnode会以错误结束,因为 erl_receive_msg 会失败,因为 fd 将指向一个关闭的套接字。

    如果要接受多个入站连接,则必须循环接受连接,并实现处理多个文件描述符的方法。你不需要一个多线程程序来完成这个任务,使用 poll select 如果您的操作系统支持SysCall。

    至于最佳连接数,我认为没有一条规则可以做到这一点,如果您希望在cnode中支持高并发性,那么就需要对应用程序进行基准测试。但在这种情况下,最好重新设计系统,以便Erlang处理并发性,从而减轻cnode的负担。

    推荐文章