首页 > Erlang并发教程 > 9.1 Erlang并发编程-防范错误数据
2013
11-18

9.1 Erlang并发编程-防范错误数据

BACK TOP文章索引

  1. 防范错误数据
  2. 共3条评论

防范错误数据

回想一下在第??章(程序??.5)中描述的那个用来分析电话号码的服务程序。它的主循环包含了以下代码:

server(AnalTable) ->
    receive
        {From, {analyse,Seq}} ->
            Result = lookup(Seq, AnalTable),
            From ! {number_analyser, Result},
            server(AnalTable);
        {From, {add_number, Seq, Key}} ->
            From ! {number_analyser, ack},
            server(insert(Seq, Key, AnalTable))
        end.

以上的Seq是一个表示电话号码的数字序列,如[5,2,4,8,9]。在编写lookup/2insert/3这两个函数时,我们应检查Seq是否是一个电话拨号按键字符[1]的列表。若不做这个检查,假设Seq是一个原子项hello,就会导致运行时错误。一个简单些的做法是将lookup/2insert/3放在一个catch语句的作用域中求值:

server(AnalTable) ->
    receive
            {From, {analyse,Seq}} ->
                case catch lookup(Seq, AnalTable) of
                        {'EXIT', _} ->
                            From ! {number_analyser, error};
                        Result ->
                            From ! {number_analyser, Result}
                    end,
                    server(AnalTable);
            {From, {add_number, Seq, Key}} ->
                From ! {number_analyser, ack},
                    case catch insert(Seq, Key, AnalTable) of
                        {'EXIT', _} ->
                            From ! {number_analyser, error},
                                server(AnalTable); % Table not changed
                        NewTable ->
                            server(NewTable)
                    end
        end.

注意,借助catch我们的号码分析函数可以只处理正常情况,而让Erlang的错误处理机制去处理badmatchbadargfunction_clause等错误。

一般来说,设计服务器时应注意即使面对错误的输入数据,服务器也不会“崩溃”。很多情况下发送给服务器的数据都来自服务器的访问函数。在上面的例子中,号码分析服务器获悉的客户端进程标识From是从访问函数获得的,例如:

lookup(Seq) ->
    number_analyser ! {self(), {analyse,Seq}},
    receive
        {number_analyser, Result} ->
            Result
    end.

服务器不需要检查From是否是一个进程标识。在这个案例中,我们(借助访问函数)来防范意外的错误情况。然而恶意程序仍然可以绕过访问函数,向服务器发送恶意数据致使服务器崩溃:

number_analyser ! {55, [1,2,3]}

这样一来号码分析器将试图向进程55发送分析结果,继而崩溃。


9.1 Erlang并发编程-防范错误数据》有 3 条评论

  1. god 说:

    快速过了一遍……

  2. 這些可能是神作 我很喜歡

  3. 這些可能是神作 我很喜歡

留下一个回复

你的email不会被公开。