关注LAMP|PHP源代码分析|web架构|PHP扩展|Erlang|服务端架构
Erlang中计算16位的MD5字符串
原创文章,转载请注明: 转载自庆亮的博客-webgame架构
本文链接地址: Erlang中计算16位的MD5字符串
erlang的bif中自带了md5计算函数,但是结果却是二进制的,即使转成list,也是10进制表示,google了一下得到一段代码用于获得字符串形式的md5结果(16位):
md5(S) ->
Md5_bin = erlang:md5(S),
Md5_list = binary_to_list(Md5_bin),
lists:flatten(list_to_hex(Md5_list)).
list_to_hex(L) ->
lists:map(fun(X) -> int_to_hex(X) end, L).
int_to_hex(N) when N < 256 ->
[hex(N div 16), hex(N rem 16)].
hex(N) when N < 10 ->
$0+N;
hex(N) when N >= 10, N < 16 ->
$a + (N-10).
英文链接 http://sacharya.com/md5-in-erlang/
| 打印文章 | 这篇文章由庆亮于2010年01月18日 10:55 上午发表在Erlang。你可以订阅RSS 2.0 也可以发表评论或引用到你的网站。 |
没有评论
没有引用
erlang zlib引起的系统崩溃记录
大约3周前 - 没有评论
之前同事遇到一个问题,系统运行一段时间后有大量的port没有正常关闭而导致beam崩溃,经过定位发现是由于zlib引起的。过程很简单,没什么技术含量,记录一下。
Erlang OTP之terminate 深入分析
大约1月前 - 没有评论
原创文章,转载请注明: 转载自庆亮的博客-webgame架构 本文链接地址: Erlang OTP之terminate 深入分析 作者:庆亮 (qing.liang.cn@gmail.com) 日期:2010-08-03 环境:centos 5.5 64 erlang 14A 一、terminate简述及问题产生 terminate是gen_server的一个回调函数,如果一个gen_server进程设置了trap_exit为true(process_flag(trap_exit, true)),则在该进程结束时会自动调用terminate。利用这个功能,我们可以在进程退出时进行一些善后工作,例如持久化数据、清理等等。但实际上terminate不一定有时间完成所有的任务,在此之前可能已经被系统强制结束了(如果使用init:stop形式结束beam)。 二、测试terminate 一个erlang 内部 process结束有两种形式:主动结束(如玩家下线后,玩家进程会自动结束)和被动结束(init:stop)。 系统停止时(init:stop/c:q/erlang:halt),会依次停止所有的进程,如果一个进程是监控树,则该监控树会先依次停止所有的子进程,然后结束自己。对于子进程也是同样的处理方法。 先做测试,后分析源码。测试分为四种情况: 进程主动退出 + simple_one_for_one init:stop + simple_one_for_one 进程主动退出 + one_for_one init:stop + one_for_one 源码文件: test.erl (application) test_sup.erl (supervisor) test_server.erl (gen_server) test.erl源码: -module(test). -behaviour(application). -export([start/0, start/2,
erlang init stop浅析
大约1月前 - 没有评论
原创文章,转载请注明: 转载自庆亮的博客-webgame架构 本文链接地址: erlang init stop浅析 作者:庆亮 (qing.liang.cn@gmail.com) 日期:2010-08-03 boot之后关注的自然是stop,直接打开erts-5.7.5/src/init.erl源码看了看: -spec stop() -> no_return(). stop() -> init ! {stop,stop}, ok. {stop,Reason} -> stop(Reason,State); 最终的调用: stop(Reason,State) -> BootPid = State#state.bootpid, {_,Progress} = State#state.status, State1 = State#state{status = {stopping, Progress}}, clear_system(BootPid,State1), do_stop(Reason,State1). 看看 clear_system/2: clear_system(BootPid,State)
erlang init boot 浅析
大约1月前 - 没有评论
原创文章,转载请注明: 转载自庆亮的博客-webgame架构 本文链接地址: erlang init boot 浅析 说明:遇到一个OTP的问题,疑惑了很久,也就有了这篇文章。 目的:跟踪Erlang的启动过程 参考这里 http://erlangdisplay.javaeye.com/blog/315497 ,直接从erts-5.7.5/src/init.erl 的boot/1函数开始(关于这个链接给出的结论以后会继续研究分析): -spec boot([binary()]) -> no_return(). boot(BootArgs) -> register(init, self()), process_flag(trap_exit, true), start_on_load_handler_process(), {Start0,Flags,Args} = parse_boot_args(BootArgs), Start = map(fun prepare_run_args/1, Start0), Flags0 = flags_to_atoms_again(Flags), boot(Start,Flags0,Args). do_boot(Init,Flags,Start) -> process_flag(trap_exit,true), {Pgm0,Nodes,Id,Path} = prim_load_flags(Flags),
erlang shell web版
大约1月前 - 没有评论
原创文章,转载请注明: 转载自庆亮的博客-webgame架构 本文链接地址: erlang shell web版 http://www.tryerlang.org/
R13B04的Emacs erlang-mode
大约3月前 - 没有评论
原创文章,转载请注明: 转载自庆亮的博客-webgame架构 本文链接地址: R13B04的Emacs erlang-mode R13B04的Emacs erlang-mode在编译后少了几个文件,默认%erlang_root%/lib/tools-2.6.5.1/emacs下有如下文件: -rw-r–r– 1 root root 183741 2010-05-21 11:43 erlang.el -rw-r–r– 1 root root 10059 2010-05-21 11:43 erlang-eunit.el -rw-r–r– 1 root root 3452 2010-05-21 11:43 erlang-start.el -rw-r–r– 1 root root 1611 2010-05-21 11:43 README -rw-r–r– 1 root root 12834 2010-05-21 11:43 test.erl.indented -rw-r–r– 1 root root 11877
mnesia脏读与事物读性能结果
大约3月前 - 没有评论
原创文章,转载请注明: 转载自庆亮的博客-webgame架构 本文链接地址: mnesia脏读与事物读性能结果 一直知道mnesia的事务比较慢,但慢到什么程度却没有一个数值的概念,今天正好有空测试一下。 上代码: -module(mnesia_read_test). -export([start/0, init_data/0, start2/0]). -record(r_test, {id, name}). start() -> statistics(wall_clock), statistics(runtime), read(), {_, Time1} = statistics(wall_clock), {_, Time2} = statistics(runtime), io:format("times:~p, wall_clock ~p, runtime:~p", [100000, Time1, Time2]). start2() -> statistics(wall_clock), statistics(runtime), read2(), {_, Time1} = statistics(wall_clock), {_,
gen_server三两话
大约4月前 - 没有评论
原创文章,转载请注明: 转载自庆亮的博客-webgame架构 本文链接地址: gen_server三两话 (最近挺忙,都没时间写点啥) gen_server是OTP中的一个重要组成,在开发中出现的频率相当高。弄明白这一块的,对于gen_server的使用有着相当好的帮忙。下面多数为代码。 从start_link开始: gen_server.erl start_link(Name, Mod, Args, Options) -> gen:start(?MODULE, link, Name, Mod, Args, Options). 跳到gen.erl,这里的GenMod值为gen_server,LinkP为link start(GenMod, LinkP, Name, Mod, Args, Options) -> case where(Name) of undefined -> do_spawn(GenMod, LinkP, Name, Mod, Args, Options); Pid -> {error, {already_started, Pid}} end. 再跳: do_spawn(GenMod, link, Name, Mod, Args, Options) -> Time = timeout(Options), proc_lib:start_link(?MODULE, init_it, [GenMod, self(), self(), Name, Mod, Args, Options], Time, spawn_opts(Options)); 跳到proc_lib.erl文件: start_link(M,F,A,Timeout,SpawnOpts) when is_atom(M), is_atom(F), is_list(A) -> Pid = ?MODULE:spawn_opt(M, F, A, ensure_link(SpawnOpts)), sync_wait(Pid, Timeout). 注意这里有个等待返回,之后需要proc_lib:init_ack来返回消息。 spawn_opt(M, F, A, Opts) when is_atom(M), is_atom(F), is_list(A) -> Parent = get_my_name(), Ancestors = get_ancestors(), check_for_monitor(Opts), erlang:spawn_opt(?MODULE, init_p, [Parent,Ancestors,M,F,A], Opts). 这里调用proc_lib模块的init_p方法: -spec init_p(pid(), [pid()], function()) -> term(). init_p(Parent, Ancestors, Fun) when is_function(Fun) -> put('$ancestors', [Parent|Ancestors]), {module,Mod} = erlang:fun_info(Fun, module), {name,Name} = erlang:fun_info(Fun, name), {arity,Arity} = erlang:fun_info(Fun, arity), put('$initial_call', {Mod,Name,Arity}), try Fun() catch Class:Reason -> exit_p(Class, Reason) end. -spec init_p(pid(), [pid()], atom(), atom(), [term()]) -> term(). init_p(Parent, Ancestors, M, F, A) when is_atom(M), is_atom(F), is_list(A) -> put('$ancestors', [Parent|Ancestors]), put('$initial_call', trans_init(M, F, A)), init_p_do_apply(M, F, A).
Erlang中日志管理三两话
大约6月前 - 没有评论
原创文章,转载请注明: 转载自庆亮的博客-webgame架构 本文链接地址: Erlang中日志管理三两话 日志系统的重要性就不罗嗦了,直接开始吧。 一、基本概念 在Erlang中,通过两个概念管理错误事情:事件管理器(event manager)和事件处理句柄(event handles)。通常各种错误、警告和消息事件都会有Erlang运行时系统发送给事件管理器。在Erlang中,默认的事情管理器为error logger,其进程名注册为error_logger。默认情况下error_logger把这些事件直接输出到控制台上。 在系统启动的一开始,error_logger只有一个简单的事件处理句柄,该处理句柄只是做缓冲和原始格式的打印操作。查看error_logger的源码,可以看到其启动过程如下: -spec start() -> {'ok', pid()} | {'error', any()}. start() -> case gen_event:start({local, error_logger}) of {ok, Pid} -> simple_logger(?buffer_size), {ok, Pid}; Error -> Error end. -spec start_link() -> {'ok', pid()}
list comprehensions与list map性能对比
大约6月前 - 没有评论
原创文章,转载请注明: 转载自庆亮的博客-webgame架构 本文链接地址: list comprehensions与list map性能对比 可以使用List comprehensions时不要 使用map或者filter,简单的性能测试对比一下: 第一组,map和list comprehensions对比,代码如下: %%map方式 -module(map_test). -export([start/1]). start(N) -> statistics(runtime), erlang:statistics(wall_clock), lists:map(fun (X) -> X*X end, lists:seq(1, N)), {_, T1} = erlang:statistics(runtime), {_, T2} = erlang:statistics(wall_clock), io:format("total times: ~p, load time: ~p (~p)", [N, T1, T2]). %%list comprehensions方式 -module(list_comp_test). -export([start/1]). start(N) -> statistics(runtime), erlang:statistics(wall_clock), [X*X || X <- lists:seq(1, N)], {_, T1} = erlang:statistics(runtime), {_, T2} = erlang:statistics(wall_clock), io:format("total times: ~p, load time: ~p (~p)", [N, T1, T2]). 测试N为1000000时结果对比: 结果取得是平均值,可以很明显的看出comprehension方式性能要高。 关于filter,则类似。不再作测试。