Erlang實戰練習(四)

2022-07-15 16:27:22 字數 4500 閱讀 4926

通過前幾次的練習實踐相信大家對erlang程式設計有了基本的認識和了解,本文通過二分搜尋、echo server、程序環三個實戰練習認識erlang中程序的通訊的基礎,通過本次實戰,主要是感受erlang建立程序、傳送訊息、接受訊息的過程,我們知道,erlang並不是共享記憶體的通訊,erlang中節點與節點、程序與程序之間的通訊都需要進行訊息傳遞,這個我已經在前幾次討論過了。

好了,廢話少說,言歸正傳吧。

練習1:二分搜尋:從乙個已排好序的列表中尋找是否包含某元素,返回true/false。

這個跟前面幾次練習一樣,溫故列表操作,**如下:

-module

(bisearch).

-export([bi_search/2,getmiddle/1,value/2,len/1]).

len() -> 0;

len([h|t]) -> 1 +len(t).

head() -> null

;head([h|t]) ->h.

value(0,l) ->

ifl =:= ->

%%io:format("hedad=false~n"),

false

; l =/= ->

%%io:format("head=~p~n",[head(l)]),

head(l)

end;

value(n,[h|t]) -> value(n-1,t).

getmiddle([h]) ->h;

getmiddle(l) ->loc = len(l) div 2,

value(loc,l).

%% 函式bi_search/2:給定乙個列表,查詢x所在的位置。

bi_search(l,x) ->middle =getmiddle(l),

ifmiddle =:= false ->

false

; middle =:= x ->

true

; middle

< x ->left = [e||e middle],

bi_search(left,x);

middle > x ->right = [e||e

bi_search(right,x)

end.

由於**是很久以前寫的,很多地方都是自己編的,沒有使用系統模組中的函式功能,因此,看起來可能比較繁瑣,例如求列表長度、求列表表頭等系統都有自定義的函式。get_middle/1主要是求出列表的中間元素。

練習2:

**如下:

-module

(echo).

-export([start/0,loop/1,print/1,stop/0]).

start() ->register(eserver,spawn_link(

fun() -> loop()end

)).

loop(x) ->

receive

stop ->io:format("server has stopped!~nsee you!~n"),

void;

term ->io:format("server received:~p~n",[term]),

loop(x)

end.

print(term) ->eserver !term. %%向程序傳送term訊息,傳送原語不是send,而是感嘆號!

stop() -> eserver ! stop.

spawn_link是erlang系統的乙個內建bif(built in function),它是用於建立乙個程序,並將當前程序與建立程序鏈結起來。

register也是erlang系統的乙個bif,它是只將乙個原子與乙個pid關聯起來,本**中原子eserver與新建立的程序關聯起來。

程式編譯執行如下:

練習3:程序環:建立n個程序,這n個程序組成乙個程序環,然後將message沿著環傳送m次。

問題中提示,可以採用兩種方法:一為集中式控制,二為分布式控制,我採用的集中式控制,先使用createprocess/2建立n-1個程序(當前程序為控制程序,也進行訊息傳遞工作),然後從第2個程序開始,使用sendmessage/4將訊息message傳遞m次,其它的函式應該很簡單,讀者自行去體驗,**如下:

-module

(ring0).

-export([start/3,genprocess/2,createprocess/2,loop/1,sendmessage/4,sleep/1,senddie/1]).

start(m,n,message) ->max =n,

createprocess(n,max),

%%process1 send m number of messages to next m process

sendmessage(2,m,message,max),

sleep(1000),

io:format("~nring transfer success!~n").

createprocess(n,max) ->l = for(n,fun(n) -> genprocess(n,max)end

).for(1,f) -> [f(1)];

for(i,f) -> [f(i)|for(i-1,f)].

genprocess(n,max) ->pron =genatom(n),

register(pron,spawn(

fun()-> loop(max) end

)), io:format("process [~p] (~p) was created success!~n",[pron,whereis(pron)]).

loop(max) ->

receive

die ->quit;

} ->io:format("message (~p) from-to: (~p) to (~p)~n",[z,from,self()]),

ify =:= 0 ->

%quit;

io:format("i am here~n");

y =/= 0 ->prom =genatom(x),

sendmessage(x,y-1,z,max)

%sleep(3000),

%prom !}

end,

loop(max)

end.

%%向process n 傳送一條訊息,此訊息需要經過m步

sendmessage(n,m,message,max) ->

ifn =:= 1 ->pid1 =whereis(genatom(max)),

pid2 =whereis(genatom(n));

n =/= 1 ->pid1 = whereis(genatom(n-1)),

pid2 =whereis(genatom(n))

end,

%%io:format("pid1= (~p) pid2 =(~p)~n",[pid1,pid2]),

ifm =:= 0 ->quit;

m =/= 0 ->

%%io:format("---message (~p) from-to: (~p) to (~p)~n",[message,pid1,pid2]),

ifn =:= max ->io:format("pass 1~n"),

pid2 ! };

%sendmessage(1, m-1, message,max),

n =/= max ->io:format("pass 2~n"),

pid2 ! }

%sendmessage(n+1,m-1,message,max)

endend

.

genatom(n) ->temp =lists:concat([process,n]),

ret =list_to_atom(temp).

senddie(n) ->pron =genatom(n),

pron !die,

ifn =:= 1 ->quit;

n =/= 1 ->senddie(n-1)

end.

sleep(t) ->

receive

after t ->

true

end.

本節主要通過2個程序建立於訊息傳遞的例子,對erlang系統訊息傳遞機制進行了實戰的講解分析,通過**分析看來,erlang訊息傳遞過程比較簡單,無非是傳送與接收的通訊。真應了那句:「周瑜打黃蓋——乙個願打,乙個願挨」,訊息傳遞也是這樣,只有你給我發訊息的時候我才能知道你對我有意思。

Erlang實戰練習(六)

本文主要講為文字建立索引,通過使用程序字典的方式為文字建立索引,儘管專家提倡盡量避免使用程序字典,但是在初學階段很容易地就使用了程序字典,當然,除了程序字典方式外,還有其它方式,後面章節我將會使用另外一種方式來儲存單詞 行數 出現次數,也即erlang提供的模組 ets erlang term st...

MySQL基礎(四) 實戰練習

資料匯入匯出 見附件 將excel檔案匯入mysql表 mysql匯出表到excel檔案 建立employee 表,包含所有員工資訊,每個員工有其對應的 id,salary 和 department id。idname salary departmentid 1joe 7000012 henry 8...

erlang基礎練習 排序

module sort export bubble 1,select1 1,select2 1 氣泡排序法 第一種 bubble l bubble sort l,length l 1 bubble sort l,0 l bubble sort h t num result bubble once h...