gpt4 book ai didi

erlang - 一个二郎 Actor 小演示

转载 作者:行者123 更新时间:2023-12-04 10:52:39 25 4
gpt4 key购买 nike

我是Erlang的菜鸟,懒得写spider的代码了:

-module(http).
-compile([export_all]).

init() ->
ssl:start(),
inets:start(),
register(m, spawn(fun() -> loop() end)),
register(fetch, spawn(fun() -> x() end)),
ok.

start() ->
L1 = [114689,114688,114691,114690], % detail page id

lists:map(fun(Gid) ->
io:format("~p ~n", [Gid]),
fetch ! {go, Gid}
end, L1),
m ! done,
done.

main(_) ->
init(),
start().

loop() ->
io:fwrite("this is in loop!!"),
receive
{no_res, Gid} ->
io:format("~p no res ! ~n", [Gid]),
loop();
{have_res, Gid} ->
io:format("~p have res ! ~n", [Gid]),
loop();
done ->
io:format("wowowow", [])
end.

x() ->
receive
{go, Gid} ->
http_post(Gid);
_ ->
ready
end.

http_post(Gid) ->
URL = "https://example.com", % url demo
Type = "application/json",
ReqArr = ["[{\"id\": \"", integer_to_list(Gid), "\"}]"],
ReqBody = string:join(ReqArr, ""),

case httpc:request(post, {URL, [], Type, ReqBody}, [], []) of
{ok, {_, _, ResBody}} ->
if
length(ResBody) =:= 0 ->
io:format("Y: ~p ~n", [Gid]);
m ! {no_res, Gid};
true ->
io:format("N: ~p ~n", [Gid])
m ! {have_res, Gid}
end;
{error, Reason} ->
io:format("error cause ~p~n", [Reason]);
_ ->
io:format("error cause ~n", [])
end.

现在,当我执行代码时,进程将立即终止,记录:

enter image description here

我有两个问题:
  • 我如何解决这个问题?
  • 如果我有几万个id在L1 ,怎么解决?产生几十个 Actor ?如果是,您如何决定 receive 的 Actor ?哪个身份证?
  • 最佳答案

    1) 而不是在 loop() 周围包装匿名函数:

    register(m, spawn(fun() -> loop() end)),

    您可以调用 spawn/3 :
    register(m, spawn(?MODULE, loop, []) ),

    同样在这里:
    register(fetch, spawn(fun() -> x() end)),

    没有。在 escript 中调用 spawn/3 不起作用 - 除非您使用以下命令预编译脚本:
    escript -c myscript.erl

    2) 一个 escript 创建一个执行 main/1 的进程您定义的功能。您的 main/1函数如下所示:
    main(_) ->
    init(),
    start().
    init()函数不循环,所以它在它调用的所有函数返回后结束,即 ssl:start() , inets:start() , register() .您的 start()函数也不循环,所以在 start() 之后返回,然后 main()返回并且因为执行 main()的进程函数无事可做,它结束了。

    3)

    How I solve this problem ?



    Http post 请求在计算机处理速度方面是永恒的,并且涉及等待,因此您可以通过同时执行多个 post 请求而不是顺序执行它们来加速您的代码。在 erlang 中,您同时执行事物的方式是产生额外的进程。在您的情况下,这意味着为每个发布请求生成一个新进程。

    您的主进程可以是一个无限循环,它位于接收等待消息中,如下所示:
    main(_) ->
    init(),
    loop().

    在哪里 init()看起来像这样:
    init() ->
    ssl:start(),
    inets:start(),
    register(loop, self()),
    ok.

    然后您可以创建一个用户界面函数,如 start()产生发布请求:
    start() ->
    L1 = [114689,114688,114691,114690], % detail page id

    lists:foreach(fun(Gid) ->
    io:format("~p ~n", [Gid]),
    spawn(?MODULE, http_post, [Gid])
    end, L1).

    ---回复评论---

    这是一个例子:
    %First line cannot have erlang code.
    main(_) ->
    init(),
    start().

    init() ->
    ssl:start(),
    inets:start().

    start() ->
    L1 = [1, 2, 3, 4],
    Self = self(),

    Pids = lists:map(fun(Gid) ->
    Pid = spawn(fun() -> http_post(Gid, Self) end),
    io:format("Spawned process with Gid=~w, Pid=~w~n", [Gid, Pid]),
    Pid
    end, L1),

    io:format("Pids = ~w~n", [Pids]),

    lists:foreach(
    fun(Pid) ->
    receive
    {no_res, {Gid, Pid} } ->
    io:format("no response! (Gid=~w, Pid=~w)~n", [Gid, Pid]);
    {have_res, {Gid, Pid, Reply}} ->
    io:format("got response: ~p~n(Gid=~w, Pid=~w)~n~n",
    [Reply, Gid, Pid]);
    {Pid, Gid, Error} ->
    io:format("Error:~n(Gid=~w, Pid=~w)~n~p~n", [Gid, Pid, Error])
    end
    end, Pids).

    http_post(Gid, Pid) ->
    URL = "http://localhost:8000/cgi-bin/read_json.py", % url demo
    Type = "application/json",
    ReqArr = ["[{\"id\": \"", integer_to_list(Gid), "\"}]"],
    ReqBody = string:join(ReqArr, ""),

    case httpc:request(post, {URL, [], Type, ReqBody}, [], []) of
    {ok, {_, _, ResBody}} ->
    if
    length(ResBody) =:= 0 ->
    io:format("Y: ~p ~n", [Gid]),
    Reply = {no_res, {Gid, self()} },
    Pid ! Reply;
    true ->
    io:format("N: ~p ~n", [Gid]),
    Reply = {have_res, {Gid, self(), ResBody} },
    Pid ! Reply
    end;
    {error, _Reason}=Error ->
    Pid ! {Gid, self(), Error};
    Other ->
    Pid ! {Gid, self(), Other}
    end.

    If I have tens of thousands of id in L1 , how solve?



    一样的方法。十万个进程在erlang中不算很多进程。

    关于erlang - 一个二郎 Actor 小演示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59398977/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com