打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Erlang网络多进程模型的实验 | Erlang非业余研究

Erlang网络多进程模型的实验

在做网络程序的时候我们会经常用到多进程模式. 主进程执行bind调用得到句柄后, 同时fork N个子进程, 把句柄传递给子进程, 多进程同时accept来处理.
这个模型在erlang下很有现实意义的. 在之前的测试中,我们演示了erlang的单处理器模式的威力,最多的时候在单cpu上可以发起40,000个tcp广播包.
但是erlang如何利用这个能力呢? 其实Erlang的port也是靠fork来实现的, 是支持这个能力的, 只不过官方的版本会在fork的时候, 把继承过来的句柄全部关闭.

让我们crack下代码来绕过这个问题.
erts/emulator/sys/unix/sys.c

1513            if(0) /*/*fork路径*/*/1514              for (i = opts->use_stdio ? 3 : 5; i < max_files; i++)1515                (void) close(i);...1581        fprintf(stderr, "cracked\n");    /*vfork路径*/1582        sprintf(fd_close_range, "%d:%d", opts->use_stdio ? 3 : 5, opts->use_stdio ? 3 : 5);

记得重新make && make install

我们下面的代码演示在主进程把一个tcp句柄传递过去, 然后在子进程中恢复成gen_tcp.

root@nd-desktop:~/otp/test# ls *.erlchild.erl  test.erlroot@ubuntu:~/otp/test# erlc *.erl

root@nd-desktop:~/otp/test# cat test.erl

-module(test).-export([start/0]).start()->process_flag(trap_exit, true),{ok, Sock} = gen_tcp:listen(0, []),{ok, Handle} = inet:getfd(Sock),Command ="erl -noshell -s child -handle " ++ integer_to_list(Handle),io:format("child command line: ~p~n", [Command]),Child = case (catch open_port({spawn, Command}, [in, {line, 256}])) of{'EXIT', Reason}->io:format("open child error, reason: ~p~n", [Reason]),halt(1);Port-> Portend,register(?MODULE, self()),io:format("STOP ME: test!stop. ~n",[]),loop(Child),io:format("bye~n",[]).loop(Child)->receive{Child, {data, Result}} ->io:format("child say: ~p~n", [Result]),loop(Child);stop->halt(0);Other->io:format("got msg: ~p~n", [Other]),loop(Child)end.

root@nd-desktop:~/otp/test# cat child.erl

-module(child).-export([start/0]).start()->{ok, [[HandleArg|_]|_]} = init:get_argument(handle),Handle = list_to_integer(HandleArg),io:format("handle: ~w~n", [Handle]),case gen_tcp:fdopen(Handle, []) of{ok, Socket} ->io:format("got socket ok: ~p~n", [Socket]);_ ->io:format("got socket fail~n", [])end,halt(0).
root@ubuntu:~/otp/test# erl -noshell -s testchild command line: "erl -noshell -s child -handle 8"crackedSTOP ME: test!stop.child say: {eol,"handle: 8"}child say: {eol,"got socket ok: #Port<0.354>"}got msg: {'EXIT',#Port<0.360>,normal}^CBREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded(v)ersion (k)ill (D)b-tables (d)istribution

Bingo! 成功实现目的!

这里给大家一个思路就是说明fork是可行的, 如果你有这个需求把上面的fork patch做好点就行.

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
回顾Erlang简要
E1.获取Elixir/Erlang版本信息
建立一个OTP应用
centos7下 rabbitmq erlang 的下载地址,的安装,源码安装,rpm安装
Erlang与JAVA的交互操作
Erlang十分钟快速入门
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服