二郎 Gen_call 对比 Gen_cast
Erlang Gen_call vs Gen_cast
Erlang OTP 说 gen_server:call
是同步的,gen_server:cast
是异步的。
经过测试,我发现gen_server:call
是同步的。
但是,gen_server:cast
会向邮箱发送消息,但 不会 运行 并行执行任务。
如何创建 多进程 到 运行?
-module(example_gen).
-behaviour(gen_server).
-export([start_link/0]).
-export([init/1,
handle_call/3,
handle_cast/2,
handle_info/2,
terminate/2,
code_change/3]).
-export([
add_bycall/2,
add_bycast/2
]).
-define(SERVER, ?MODULE).
-record(state, {}).
add_bycall(Key, Value) ->
gen_server:call(?SERVER, {bycall, Key, Value}).
add_bycast(Key, Value) ->
gen_server:cast(?SERVER, {bycast, Key, Value}).
example(Key, Value) ->
timer:sleep(2000),
io:format("finished [~p, ~p] at [~p] ~n", [Key, Value, erlang:system_time(milli_seconds)]).
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
init([]) ->
{ok, #state{}}.
handle_call({bycall, Key, Value}, _From, State) ->
example(Key, Value),
{reply, ok, State};
handle_call(_Request, _From, State) ->
{reply, ok, State}.
handle_cast({bycast, Key, Value}, State) ->
example(Key, Value),
{noreply, State};
handle_cast(_Request, State) ->
{noreply, State}.
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
运行宁代码
[example_gen:add_bycall(K, K) || K <- lists:seq(1, 10) ].
[example_gen:add_bycast(K, K) || K <- lists:seq(1, 10) ].
术语同步和异步与术语串行和正交并行。 gen_server:call/2,3
与调用者同步,gen_server:cast/2
与调用者异步。一个 gen_server
执行的工作始终是连续的,因为它是由一个进程执行的。
术语异步和同步在这种情况下是什么意思。如果你有代码
gen_server:call(S, foo),
bar(),
由 foo
触发的工作总是在 bar/0
之前执行,而 bar/0
总是在工作 foo
完成之后执行。因此 foo
和 bar/0
是 同步的 。如果你有代码
gen_server:cast(S, foo),
bar(),
由 foo
触发的工作可以在 bar/0
之前、之后甚至在 SMP 系统上并行执行。因此 foo
和 bar/0
是 异步的 。 同步在调用者和被调用者之间很重要。
Erlang OTP 说 gen_server:call
是同步的,gen_server:cast
是异步的。
经过测试,我发现gen_server:call
是同步的。
但是,gen_server:cast
会向邮箱发送消息,但 不会 运行 并行执行任务。
如何创建 多进程 到 运行?
-module(example_gen).
-behaviour(gen_server).
-export([start_link/0]).
-export([init/1,
handle_call/3,
handle_cast/2,
handle_info/2,
terminate/2,
code_change/3]).
-export([
add_bycall/2,
add_bycast/2
]).
-define(SERVER, ?MODULE).
-record(state, {}).
add_bycall(Key, Value) ->
gen_server:call(?SERVER, {bycall, Key, Value}).
add_bycast(Key, Value) ->
gen_server:cast(?SERVER, {bycast, Key, Value}).
example(Key, Value) ->
timer:sleep(2000),
io:format("finished [~p, ~p] at [~p] ~n", [Key, Value, erlang:system_time(milli_seconds)]).
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
init([]) ->
{ok, #state{}}.
handle_call({bycall, Key, Value}, _From, State) ->
example(Key, Value),
{reply, ok, State};
handle_call(_Request, _From, State) ->
{reply, ok, State}.
handle_cast({bycast, Key, Value}, State) ->
example(Key, Value),
{noreply, State};
handle_cast(_Request, State) ->
{noreply, State}.
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
运行宁代码
[example_gen:add_bycall(K, K) || K <- lists:seq(1, 10) ].
[example_gen:add_bycast(K, K) || K <- lists:seq(1, 10) ].
术语同步和异步与术语串行和正交并行。 gen_server:call/2,3
与调用者同步,gen_server:cast/2
与调用者异步。一个 gen_server
执行的工作始终是连续的,因为它是由一个进程执行的。
术语异步和同步在这种情况下是什么意思。如果你有代码
gen_server:call(S, foo),
bar(),
由 foo
触发的工作总是在 bar/0
之前执行,而 bar/0
总是在工作 foo
完成之后执行。因此 foo
和 bar/0
是 同步的 。如果你有代码
gen_server:cast(S, foo),
bar(),
由 foo
触发的工作可以在 bar/0
之前、之后甚至在 SMP 系统上并行执行。因此 foo
和 bar/0
是 异步的 。 同步在调用者和被调用者之间很重要。