zoukankan      html  css  js  c++  java
  • ellang 中进程异步通信中的信箱与保序

    erlang 进程通讯中 执行到 receive 语句时 如果信箱没有消息可以匹配时会暂停等待消息. 

    go() ->
        register(echo, spawn(test_pid,loop,[])),
        echo ! {self(), hello},
        receive
            {_Pid,Msg} ->
                io:format("~w~n",[Msg])
        end.
        %%Pid ! stop.
    
    loop() ->
        io:format(" loop start~n", []),
        receive
            {From, Msg} ->
                io:format(" loop : ~w | ~w~n", [From, Msg]), From ! {self(), Msg},
                loop();
            stop  -> io:format(" loop : ~w~n", [stop]), true
            %%    true
        end.

    由于信箱是先进先出,向同一个进程发送的消息,处理返回一定是保序的。 但这只限于一直不出错,匹配成功的情况,比如 revecie支持 timeOut, timeOut 后 进程将不在主动响应, 但是还能接收信息.

    read(Db, Key) ->
        Db ! {self(), {read, Key}},
        receive
            {read, R} -> {ok, R};
            {error, Reason} -> {error, Reason}
        after 10000 -> {error, timeout}
        end.
    
    db() ->
        receive
            {Pid, {read, 2}} -> Pid ! {read, 2},db();
            {Pid, {read, 3}} -> Pid ! {read, 3},db();
            {Pid, {read, 5}} -> Pid ! {error, "not Reason"},db()
        end.

    假如 有以下调用(Db 是个查询进程,查询完毕会给当前进程返回查询结果)

    read(Db, 1).

    read(Db, 2).

    //after 1500

    read(Db, 6).

    如果 read(Db, 1). 触发了timeout,  而且 read(Db, 2). 返回了{read, R}. 那么这时信箱处于阻塞状态,当read(Db,6).执行时, 会从信箱中取出第一条匹配返回. 所以 read(Db, 6).会返回 {ok, 2}.

    如果是在终端直接运行测试,可以这样写

    read(Db, Key) ->
        Db ! {self(), {read, Key}},
        receive
            {read, R} -> {ok, R};
            {error, Reason} -> {error, Reason}
        after 10000 -> test(self()), {error, timeout}
        end.
    
    db() ->
        receive
            {Pid, {read, 2}} -> Pid ! {read, 2},db();
            {Pid, {read, 3}} -> Pid ! {read, 3},db();
            {Pid, {read, 5}} -> Pid ! {error, "not Reason"},db()
        end.
    
    test(Pid) ->
        Pid ! {read, 2}.

    在timeout 的时候往信箱里塞一条信息,然后你会看到

    所以这时候,信箱的顺序就是错乱的, 那解决办法呢,一种是每次匹配前清理上一条消息,另一种则是加个唯一标识收到消息时匹配下是不是自己要的信息.

  • 相关阅读:
    CND库(Bootstrap 、React、Vue、Angular.js、JQuery)
    使用线性渐变实现滚动进度条
    设置鼠标光标样式
    百度地图API部分功能
    网页的三种布局(固定布局,流式布局,弹性布局)
    这一次带你彻底了解远程Cookie操作
    js获取各种高度和宽度
    点击按钮,回到页面顶部的5种写法
    Chrome默认字体大小
    CSS Grid 网格布局
  • 原文地址:https://www.cnblogs.com/bobolive/p/3171076.html
Copyright © 2011-2022 走看看