一直想知道,erlang进程hibernate会不会把状态值给删除,通过代码知道,不会。
-module(hibernate_procs).
-behaviour(gen_server).
-export([start_link/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-define(SERVER, ?MODULE).
-record(state, {}).
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
init([]) ->
process_flag(trap_exit, true),
{ok, #state{}}.
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info({put, Key, Value}, State) ->
io:format("I am :~p~n", [self()]),
put(Key, Value),
{noreply, State};
handle_info(hibernate_proc, State) ->
io:format("hibernate, I am:~p~n", [self()]),
{noreply, State, hibernate};
handle_info(get_info, State) ->
io:format("all the get() info:~p~n", [get()]),
{noreply, State};
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
测试过程:
$erlc hibernate_procs.erl
$erl
1> {ok, Pid} = hibernate_procs:start_link().
2>[Pid ! {put , I, I} || I <- lists:seq(1, 20)].
3> rp(process_info(Pid)).
[{registered_name,hibernate_procs},
{current_function,{gen_server,loop,6}},
{initial_call,{proc_lib,init_p,5}},
{status,waiting},
{message_queue_len,0},
{messages,[]},
{links,[<0.36.0>]},
{dictionary,[{'$initial_call',{hibernate_procs,init,1}},
{20,20},
{19,19},
{18,18},
{17,17},
{16,16},
{'$ancestors',[<0.36.0>]},
{15,15},
{14,14},
{13,13},
{12,12},
{11,11},
{10,10},
{9,9},
{8,8},
{7,7},
{6,6},
{5,5},
{4,4},
{3,3},
{2,2},
{1,1}]},
{trap_exit,true},
{error_handler,error_handler},
{priority,normal},
{group_leader,<0.27.0>},
{total_heap_size,1220},
{heap_size,610},
{stack_size,9},
{reductions,477},
{garbage_collection,[{min_bin_vheap_size,46422},
{min_heap_size,233},
{fullsweep_after,65535},
{minor_gcs,2}]},
{suspending,[]}]
4>Pid ! hibernate_proc.
5>rp(process_info(Pid)).
[{registered_name,hibernate_procs},
{current_function,{erlang,hibernate,3}},
{initial_call,{proc_lib,init_p,5}},
{status,waiting},
{message_queue_len,0},
{messages,[]},
{links,[<0.36.0>]},
{dictionary,[{'$initial_call',{hibernate_procs,init,1}},
{20,20},
{19,19},
{18,18},
{17,17},
{16,16},
{'$ancestors',[<0.36.0>]},
{15,15},
{14,14},
{13,13},
{12,12},
{11,11},
{10,10},
{9,9},
{8,8},
{7,7},
{6,6},
{5,5},
{4,4},
{3,3},
{2,2},
{1,1}]},
{trap_exit,true},
{error_handler,error_handler},
{priority,normal},
{group_leader,<0.27.0>},
{total_heap_size,96},
{heap_size,96},
{stack_size,0},
{reductions,498},
{garbage_collection,[{min_bin_vheap_size,46422},
{min_heap_size,233},
{fullsweep_after,65535},
{minor_gcs,2}]},
{suspending,[]}]
可以看到,更新了20个数据到进程字典里面,通过hibernate操作,可以把total_heap_size、heap_size给减少很多,而且可以看到,当前进程的确是在运算erlang, hibernate函数。这里用的是gen_server模块,它里面调用了proc_lib:hibernate函数,proc_lib:hibernate函数通过try...catch调用erlang:hibernate函数。有利于我们调试和调用。