ITKeyword,专注技术干货聚合推荐

注册 | 登录

Erlang 秘笈

skyremember 分享于 2008-09-19

2020腾讯云共同战“疫”,助力复工(优惠前所未有!4核8G,5M带宽 1684元/3年),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1054

2020阿里云最低价产品入口,含代金券(新老用户有优惠),
地址https://www.aliyun.com/minisite/goods

Erlang 秘笈

来源: LUPA开源社区

http://www.lupaworld.com/action-viewstutorial-itemid-10194.html

 
文章来源于http://www.lupaworld.com

上次说请 mryufeng 同学多写写研究心得,还推说不大爱写长东西。隔不了几天,跑到他的 blog 上一看,乖乖龙的东!整了一大堆秘笈,原来是要藏私!说不得,对于这样同志,只能揪出来示众了。注意,以下内容全部是“海贼版”,未经作者明确同意,请慎入!

1, erl CTRL+C 的未公开功能

在erl shell下按下CTRL+C的时候,显示:

  1. BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
  2.          (v)ersion (k)ill (D)b-tables (d)istribution

注:*nix 下的 erl 才有,windows 下的 erl 按 ctrl+C 就直接退出了。

但是实际上可以有更多功能,看代码:

  1. while (1) {
  2.     if ((i = sys_get_key(0)) <= 0)
  3.         erl_exit(0, "");
  4.     switch (i) {
  5.     case 'q':
  6.     case 'a':
  7.     case '*': /*
  8.            * The asterisk is an read error on windows,
  9.            * where sys_get_key isn't that great in console mode.
  10.            * The usual reason for a read error is Ctrl-C. Treat this as
  11.            * 'a' to avoid infinite loop.
  12.            */
  13.         erl_exit(0, "");
  14.     case 'A':        /* Halt generating crash dump */
  15.         erl_exit(1, "Crash dump requested by user");
  16.     case 'c':
  17.         return;
  18.     case 'p':
  19.         process_info(ERTS_PRINT_STDOUT, NULL);
  20.         return;
  21.     case 'm':
  22.         return;
  23.     case 'o':
  24.         port_info(ERTS_PRINT_STDOUT, NULL);
  25.         return;
  26.     case 'i':
  27.         info(ERTS_PRINT_STDOUT, NULL);
  28.         return;
  29.     case 'l':
  30.         loaded(ERTS_PRINT_STDOUT, NULL);
  31.         return;
  32.     case 'v':
  33.         erts_printf("Erlang (%s) emulator version "
  34.                ERLANG_VERSION "/n",
  35.                EMULATOR);
  36.         erts_printf("Compiled on " ERLANG_COMPILE_DATE "/n");
  37.         return;
  38.     case 'd':
  39.         distribution_info(ERTS_PRINT_STDOUT, NULL);
  40.         return;
  41.     case 'D':
  42.         db_info(ERTS_PRINT_STDOUT, NULL, 1);
  43.         return;
  44.     case 'k':
  45.         process_killer();
  46.         return;
  47. #ifdef OPPROF
  48.     case 'X':
  49.         dump_frequencies();
  50.         return;
  51.     case 'x':
  52.         {
  53.         int i;
  54.         for (i = 0; i <= HIGHEST_OP; i++) {
  55.             if (opc[i].name != NULL) {
  56.             erts_printf("%-16s %8d/n", opc[i].name, opc[i].count);
  57.             }
  58.         }
  59.         }
  60.         return;
  61.     case 'z':
  62.         {
  63.         int i;
  64.         for (i = 0; i <= HIGHEST_OP; i++)
  65.             opc[i].count = 0;
  66.         }
  67.         return;
  68. #endif
  69. #ifdef DEBUG
  70.     case 't':
  71.         p_slpq();
  72.         return;
  73.     case 'b':
  74.         bin_check();
  75.         return;
  76.     case 'C':
  77.         abort();
  78. #endif
  79.     case '/n':
  80.         continue;
  81.     default:
  82.         erts_printf("Eh?/n/n");
  83.     }
  84.     }

注:就是说,除了 a c p i l v k D d 之外,还有 A m o X x z ,如果在 DEBUG 下编译的,还有 t b C 可以用。

好多调试用的功能 希望对大家有用。

2,如何看erts内部的状态

经常在性能优化的时候 要看下erts内部的允许状态 erlang有未公开的函数

erts_debug:get_internal_state(XX)

XX为atom有以下几个
DECL_AM(node_and_dist_references);
DECL_AM(DbTable_words);
DECL_AM(next_pid);
DECL_AM(next_port);
DECL_AM(check_io_debug);
DECL_AM(available_internal_state);
DECL_AM(monitoring_nodes);

XX为list有以下几个
DECL_AM(link_list);
DECL_AM(monitor_list);
DECL_AM(channel_number);
DECL_AM(have_pending_exit);

可以看的很细节的运行期数据,前提是先用 erts_debug:set_internal_state(available_internal_state, true). 否者调用 get_internal_state 会提示失败.

3,erlang inet:setopts 未公开选项

inet:setopt有packet设置选项:

  1. {packet, PacketType} (TCP/IP sockets)
  2.     Defines the type of packets to use for a socket. The following values are valid:
  3.  
  4.     raw | 0
  5.         No packaging is done.
  6.     1 | 2 | 4
  7.         Packets consist of a header specifying the number of bytes in the packet, followed by that number of bytes. The length of header can be one, two, or four bytes; the order of the bytes is big-endian. Each send operation will generate the header, and the header will be stripped off on each receive operation.
  8.     asn1 | cdr | sunrm | fcgi | tpkt | line
  9.         These packet types only have effect on receiving. When sending a packet, it is the responsibility of the application to supply a correct header. On receiving, however, there will be one message sent to the controlling process for each complete packet received, and, similarly, each call to gen_tcp:recv/2,3 returns one complete packet. The header is not stripped off.
  10.         The meanings of the packet types are as follows:
  11.         asn1 - ASN.1 BER,
  12.         sunrm - Sun's RPC encoding,
  13.         cdr - CORBA (GIOP 1.1),
  14.         fcgi - Fast CGI,
  15.         tpkt - TPKT format [RFC1006],
  16.         line - Line mode, a packet is a line terminated with newline, lines longer than the receive buffer are truncated.

文档中写的就这么多了 其实还有2个选项:http, httph 用于解释http的请求,实现在 otp_src_R11B-5/erts/emulator/drivers/common/inet_drv.c 里:

  1. #ifdef USE_HTTP
  2. ...
  3.     #endif
  4.  
  5. /*
  6. ** load http message:
  7. **  {http_eoh, S}                          - end of headers
  8. **  {http_header,   S, Key, Value}         - Key = atom() | string()
  9. **  {http_request,  S, Method,Url,Version}
  10. **  {http_response, S, Version, Status, Message}
  11. **  {http_error,    S, Error-Line}
  12. */

消息以上面的方式发给process,用于 gen_tcp 由于在driver层面实现的,所以效率就很高,对于编写http隧道之类的程序 很有帮助哦。

注:得到一个提示,如果要在 erlang 中以极高的效率来实现某个东西,可以在 driver 层面入手。

4,erl_call erlang cnode 功能强大

otp_src_R11B-5/lib/erl_interface/src/prog/erl_call.c 是个不错的工具, 就是ei的前端能够通过cnode给erlang的后端发各种请求。

具体的见主题: 如何把erlang应用在项目中?

  1. where: -a  apply(Mod,Fun,Args) (e.g -a 'erlang length [[a,b,c]]'
  2.          -c  cookie string; by default read from ~/.erlang.cookie
  3.          -d  direct Erlang output to ~/.erl_call.out.
  4.          -e  evaluate contents of standard input (e.g echo "X=1,Y=2,{X,Y}."|erl_call -e ...)
  5.          -h  specify a name for the erl_call client node
  6.          -m  read and compile Erlang module from stdin
  7.          -n  name of Erlang node, same as -name
  8.          -name  name of Erlang node, expanded to a fully qualified
  9.          -sname name of Erlang node, short form will be used
  10.          -q  halt the Erlang node (overrides the -s switch)
  11.          -r  use a random name for the erl_call client node
  12.          -s  start a new Erlang node if necessary
  13.          -v  verbose mode, i.e print some information on stderr
  14.          -x  use specified erl start script, default is erl

使用方法 :
1. erl -name xx@192.168.0.98 启动后端
2. export EI_TRACELEVEL=6
i. erl_call -v -d -n xx@erl98.3322.org -m 模块方式 ( -v -d 调试和verbose模式)
如: -module(a).
CTRL+D
ii. erl_call -v -d -n xx@erl98.3322.org -e 表达式方式
如: 1+2.
CTRL+D
iii. erl_call -v -d -n xx@erl98.3322.org -a ‘erlang length [[a,b,c]]’

这两种都是从stdin读 直到你按下CTRL+D, 然后你就可以看到结果。

另外,这只程序有内存泄漏

  1. *    Note: We don't free any memory at all since we only
  2. *    live for a short while.

而且 erl_call.c有bug,第812行

  1. free(mbuf);            /* Allocated in read_stdin() */

注释掉这行就可以了

这个程序默认是不安装带标准发布目录去的。

从这个程序 我们可以知道cnode 能作的事情受限于你的想像力。

注:
ping erl98.3322.org
PING erl98.3322.org (192.168.0.98) 56(84) bytes of data.

由于erl_call程序有点小问题 -n xx@erl98.3322.org 最好用域名 否者erl_call就抓狂了。

copy & paste 后感:“非业余研究”就是不一样啊,硕果累累的。mryufeng 同学,好样的!



  • 读《谈分布式网络程序设计》,思Erlang (发布于 2007-10-19)

    原文地址:avindev.javaeye.com 原文作者:AvinDev 163的zhousen写了几篇文章,《谈分布式网络程序设计》 第一篇,第二篇,第三篇 简单谈谈感想。 1.网络数据的收发的设计方式 文中说: 使用select,一个线程专门负责所有的连接的接受和发送 通常在高性能的服务器程序 则使用的是第二种方式,占系统资源少,而且性能也很好。此外,流水线技术是目前cpu中最基本的技术之一,若将此用于网络程序设计,也可以大幅. ...查看

  • 公布 mryufeng 同学的 Erlang 秘笈 (发布于 2007-10-19)

    上次说请 mryufeng 同学多写写研究心得,还推说不大爱写长东西。隔不了几天,跑到他的 blog 上一看,乖乖龙的东!整了一大堆秘笈,原来是要藏私!说不得,对于这样同志,只能揪出来示众了。注意,以下内容全部是“海贼版”,未经作者明确同意,请慎入! 1, erl CTRL+C 的未公开功能 在erl shell下按下CTRL+C的时候,显示: BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded    . ...查看

  • Erlang与JAVA的交互操作 (发布于 2007-10-19)

    试了一下传说中的 JInterface ,使用 OtpErlang.jar 的整个过程其实非常简单,似乎比 JMS 的程序都简单。 首先,我们要用 java 实现的原始 erlang 程序如下,没错,就是巨简单的 echo ,我们的目标是要把它用 java 来改写,不仅写服务端,也要写客户端。 下载: echo_client.erl -module(echo_client).   -export([run/0]).   run() ->     Msg = &quo. ...查看

  • Erlang单元测试 Unit Test in Erlang (发布于 2007-10-19)

    Erlang被称作是“工业级的语言”,在测试领域,理应是有相当成熟度的。而,Joe老先生本人,也是崇尚“拿测试结果说话”的人(在 《Programming Erlang》书中,上来就搞测试,然后再开讲的例子比比皆是)。就连 Erlang/OTP 本身的代码质量也是有严密的测试作为保障的。所以,如果在Erlang领域,你见到远比其他语言为多的测试相关工具、框架、包,丝毫也不应该感到惊奇。下 面,我们就来看看&ldq. ...查看

  • erlang网络编程的几个性能调优和注意点 (发布于 2007-10-19)

    前些天给echo_server写了个非常简单的连接压力测试程序, 代码   -module(stress_test).      -export([start/0, tests/1]).      start() ->       tests(12345).      tests(Port) ->      &nbs. ...查看


    http://www.lupaworld.com/category-440.html

Erlang 秘笈 来源: LUPA开源社区 http://www.lupaworld.com/action-viewstutorial-itemid-10194.html   文章来源于http://www.lupaworld.com 上次说请 mryufeng 同学多写写研究心得,还推说不大

相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。