Erlang是一种函数式编程语言,以并发处理闻名。它提供了许多强大的工具和库,帮助开发者处理并发任务。本文将介绍一些Erlang中的并发处理实战案例,展示其强大的并发能力。
1. 并发服务器
在Erlang中,我们可以轻松地编写并发服务器。以下是一个简单的示例,演示了如何创建一个支持并发连接的TCP服务器:
-module(server).
-export([start/1]).
start(Port) ->
{ok, Listen} = gen_tcp:listen(Port, [{active, false}, {reuseaddr, true}]),
loop(Listen).
loop(Listen) ->
{ok, Socket} = gen_tcp:accept(Listen),
spawn(fun() -> handle(Socket) end),
loop(Listen).
handle(Socket) ->
case gen_tcp:recv(Socket, 0) of
{ok, Request} ->
Response = process_request(Request),
gen_tcp:send(Socket, Response),
handle(Socket);
{error, closed} -> ok
end.
process_request(Request) ->
% 处理请求的代码
上述代码创建了一个TCP服务器,侦听特定的端口。每当有新的连接请求到来时,将会创建一个新的进程来处理连接。这样,服务器就可以并发处理多个连接,而不会阻塞其他连接。
2. 并发任务执行
在Erlang中,我们可以使用spawn/1
函数来创建新的进程执行并发任务。以下是一个示例,展示了如何同时执行多个并发任务:
-module(concurrent_tasks).
-export([start/1]).
start(NumTasks) ->
TaskRefs = [spawn(fun() -> process_task(TaskNumber) end) || TaskNumber <- lists:seq(1, NumTasks)],
wait_for_tasks(TaskRefs).
process_task(TaskNumber) ->
% 执行任务的代码
wait_for_tasks([]) -> ok;
wait_for_tasks(TaskRefs) ->
receive
{TaskRef, Result} ->
io:format("Task ~p completed with result ~p~n", [TaskRef, Result]),
wait_for_tasks(lists:delete(TaskRef, TaskRefs))
end.
上述示例代码使用了spawn/1
函数来创建指定数量的并发任务。每个任务将会在一个新的进程中执行。wait_for_tasks/1
函数等待所有任务执行完成并输出结果。
3. 并发消息传递
Erlang以消息传递作为主要的并发通信机制。以下是一个示例,展示了如何在不同进程间进行消息传递:
-module(message_passing).
-export([start/1]).
start(NumWorkers) ->
ManagerPid = spawn(fun() -> manager(NumWorkers) end),
ManagerPid ! {self(), start},
receive
{manager_started, ManagerPid} ->
io:format("Manager started with PID ~p~n", [ManagerPid])
end.
manager(NumWorkers) ->
io:format("Manager started~n"),
Workers = [spawn_link(fun() -> worker(ManagerPid) end) || _ <- lists:seq(1, NumWorkers)],
io:format("Spawned ~p workers~n", [NumWorkers]),
loop(Workers, []).
loop(Workers, CompletedTasks) ->
receive
{From, start} ->
TaskPid = hd(Workers),
NewWorkers = tl(Workers),
TaskPid ! {self(), task},
loop(NewWorkers, [{From, TaskPid} | CompletedTasks]);
{worker_completed, TaskPid, Result} ->
case lists:keyfind(TaskPid, 2, CompletedTasks) of
{From, _} ->
From ! {task_completed, Result},
loop(Workers ++ [spawn_link(fun() -> worker(self()) end)], lists:keydelete(TaskPid, 2, CompletedTasks))
end
end.
worker(ManagerPid) ->
io:format("Worker started with PID ~p~n", [self()]),
loop(ManagerPid).
loop(ManagerPid) ->
receive
{From, task} ->
% 执行任务的代码
Result = do_task(),
ManagerPid ! {worker_completed, self(), Result},
loop(ManagerPid)
end.
do_task() ->
% 执行任务的代码
上述示例代码创建了一个任务管理器进程和多个工作进程。任务管理器将会等待外部命令,然后将任务分发给空闲的工作进程。工作进程完成任务后,将结果发送回任务管理器。任务管理器将结果发送给任务的发送方。
总结:Erlang提供了许多丰富的机制和工具,用于处理并发任务。无论是创建并发服务器、执行并发任务还是进行并发消息传递,Erlang都是一个非常强大的选择。希望本文的案例能够帮助您更好地理解Erlang的并发处理能力。
本文来自极简博客,作者:琉璃若梦,转载请注明原文链接:Erlang并发处理实战案例