`

erlang学习笔记(并发程序设计)

 
阅读更多

 See Also: http://www.erlang.org/course/concurrent_programming.html

Definitions

Creating a new process

Simple message passing

An Echo Process

Selective Message Reception

Selection of Any Message

A Telephony Example

Pids can be sent in messages

Registered Processes

The Client Server Model

Timeouts

 

Definitions定义

Process 轻量级进程,系统会有许多同时运行的process
Message	进程间通过消息通讯
Timeout	超时机制
Registered Process	注册了名称的进程
Client/Server Model

Creating a new process创建一个新进程

 

Pid1进程中执行如下代码
Pid2 = spawn(Mod,Func,Args)
Pid2是新进程的标识,只有Pid1知道

 

Simple Message Passing消息传递

 

%mesTest.erl

-module(mesTest).
-export([recvTest/0]).

recvTest() ->
        receive
                finished ->
                        io:format("program stopped!~n",[]);
                {From,Msg} ->
                        io:format("Received ~p ~p~n", [From,Msg])
        end.

1> c(mesTest).
{ok,mesTest}
2> Pid2 = spawn(mesTest,recvTest,[]).
<0.39.0>
3> Pid2!{self(),"Hello Pid2"}.
Receoved <0.32.0> "Hello Pid2"
{<0.32.0>,"Hello Pid2"}
4> Pid2!{self(),"Hello Pid2"}.	%Pid2进程已经结束
{<0.32.0>,"Hello Pid2"}
5>

self() 返回自身进程的pid

From 和 Msg 匹配收到的消息 (也可以调用Pid2!finished)

如果From之前已经被bound数据,那只有Msg会收到内容

An Echo Process

% echo.erl
-module(echo).
-export([go/0, loop/0]).
 
go() ->
Pid2 = spawn(echo, loop, []),
Pid2 ! {self(), hello},
receive 
{Pid2, Msg} ->
io:format("P1 ~w~n",[Msg])
end,
Pid2 ! stop.

loop() ->
receive
{From, Msg} -> 
From ! {self(), Msg},
loop();
stop ->
true
end.

执行echo:go().

Selective Message Reception

% echo.erl
-module(echo).
-export([test/0,selective/0,bfunc/1]).

selective() ->
        receive
                foo ->
                        io:format("Received foo from A~n",[])
        end,
        receive
                bar ->
                        io:format("Received bar from B~n",[])
        end.

bfunc(Cpid) ->
        Cpid ! bar.

test() ->
        Cpid = spawn(echo, selective, []),
        spawn(echo, bfunc, [Cpid]),
timer:sleep(1000),
        Cpid ! foo.
1> c(echo).
{ok,echo}
2> echo:test().
Received foo from A
foo
Received bar from B

Selection of Any Message

-module(echo).
-export([test/0,selective/0,bfunc/1]).
selective() ->
        receive
                Msg ->
                        io:format("Received ~w ~n",[Msg])
        end,
        receive
                Msg2 ->
                        io:format("Received ~w ~n",[Msg2])
        end.

bfunc(Cpid) ->
        Cpid ! bar.

test() ->
        Cpid = spawn(echo, selective, []),
        spawn(echo, bfunc, [Cpid]),
        timer:sleep(1000),
        Cpid ! foo.

1> c(echo).
{ok,echo}
2> echo:test().
Received bar
Received foo
foo

A Telephony Example

%这个例子没能理解

 

Pids can be sent in messages

% A 把自己的Pid发送给B,B再将A的pid给C,最终C直接向A回话
% echo.erl
-module(echo).
-export([test/0,bfunc/0,cfunc/0]).

cfunc() ->
        receive
                {_,Apid} ->
                        Apid ! foo
        end.

bfunc() ->
        receive
                {Cpid,Apid} ->
                        Cpid ! {"Call A",Apid}
        end.

test() ->
        %create b and c process
        Bpid = spawn(echo,bfunc,[]),
        Cpid = spawn(echo,cfunc,[]),

        Bpid ! {Cpid,self()},
        receive
                Mes ->
                        io:format("Received ~w from C ~n",[Mes])
        end.

1> c(echo).
{ok,echo}
2> echo:test().
Received foo from C
ok

Registered Processes

register(Alias, Pid) Registers the process Pid with the name Alias.

% echo.erl
-module(echo).
-export([test/0,bfunc/0,cfunc/0]).

cfunc() ->
        receive
                {_,Apid} ->
                        Apid ! foo
        end.

bfunc() ->
        receive
                {_,Apid} ->
                        cpid ! {"Call A",Apid}
        end.

test() ->
        %create b and c process
        Bpid = spawn(echo,bfunc,[]),
        Cpid = spawn(echo,cfunc,[]),
        register(cpid,Cpid),	%BPid可以通过cpid直接向C发送消息了

        Bpid ! {Cpid,self()},
        receive
                Mes ->
                        io:format("Received ~w from C ~n",[Mes])
        end.

Client Server Model

% myserver.erl
-module(myserver).
-export([start/0,server/0,request/1]).

handle(Reqdata) ->
        "Hello " ++ Reqdata.

server() ->
        io:format("server id = ~w ~n",[self()]),
        receive
                [From,{request,X}] ->
                        Resp = handle(X),
                        From ! {reply,Resp},
                        server()
        end.

start() ->
        register(serverid,spawn(myserver,server,[])).

request(Name) ->
        serverid ! [self(),{request,Name}],
        receive
                {reply,Res} ->
                        io:format("Get ~p from server!",[Res])
        after 5000 ->
                io:format("No response from server~n",[]),
                exit(timeout)
        end.

1> c(myserver).
{ok,myserver}
2> myserver:start().
server id = <0.39.0>
true
3> myserver:request("PJ").
server id = <0.39.0>
Get "Hello PJ" from server!ok
4>

Uses of Timeouts

分享到:
评论

相关推荐

    erlang 学习笔记1

    【描述】虽然描述中没有具体的信息,但我们可以假设这是一个博主分享的关于Erlang学习的初步笔记,可能涵盖了基本语法、并发模型以及一些实用工具的使用。 【标签】"源码"和"工具"提示我们,这篇笔记可能包括了...

    redis 的学习笔记A

    随着互联网技术的发展,特别是Web2.0时代,高并发、大数据量的场景增多,传统的关系型数据库在扩展性和性能上面临挑战。NoSQL数据库应运而生,它们通常具有分布式、水平扩展、高可用性等特点,能够更好地适应现代...

    ericssonaxel.github.io:evm.com

    【描述】"帖子" 提示我们这个项目可能包含了一系列的文章或博客帖子,这些帖子可能涵盖了Erlang语言的学习笔记、EVM的内部工作原理、如何使用Erlang进行并发编程、Erlang在分布式系统中的应用,以及与SCSS(Sassy ...

    rabbitmq笔记及面试要点

    选择RabbitMQ的理由包括其对AMQP标准的全面支持,提供高度可靠的消息持久化功能,以及强大的高并发处理能力,这得益于Erlang语言的天然优势。此外,RabbitMQ的集群部署简单,社区活跃,使得它成为许多企业的首选。 ...

    compsci390-plp

    此外,这还可能包含课程的项目要求,例如设计和实现一个小的编译器或解释器,或者使用Erlang构建一个并发应用程序。 综上所述,"compsci390-plp"课程涵盖了编程语言的深度学习,重点是Erlang语言的实践应用。学生将...

    RabbitMQ.doc

    - Erlang是一种支持并发的编程语言,用于运行RabbitMQ。 - 配置环境变量`ERLANG_HOME`和`Path`。 - **安装RabbitMQ**: - 下载并安装RabbitMQ,注意版本兼容性。 - **安装插件**: - 在指定目录运行命令`...

    Walter3semestre

    Elixir 是一种基于 Erlang VM(BEAM)的函数式编程语言,设计用于构建可扩展的并发系统,常用于分布式和实时系统。 在压缩包 "Walter3semestre-main" 中,我们通常可以期待找到一系列与 Elixir 编程相关的资源,...

Global site tag (gtag.js) - Google Analytics