- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正处于学习 Erlang 的早期阶段,我需要一些进一步的帮助。不确定这是否会得到任何阳光,但它就在这里......我正在寻找关于该示例如何工作的流程图。
示例代码:
https://github.com/erlware/Erlang-and-OTP-in-Action-Source/blob/master/chapter_03/tr_server.erl
让我解释一下我的问题...
1> tr_server:start_link().
init([Port]) ->
{ok, LSock} = gen_tcp:listen(Port, [{active, true}]),
{ok, #state{port = Port, lsock = LSock}, 0}.
lists:reverse([1,2,3]).
get_count() ->
gen_server:call(?SERVER, get_count).
stop() ->
gen_server:cast(?SERVER, stop).
最佳答案
在数据来自 tcp 端口和服务器通过 handle_info 回调处理此情况的情况下,您似乎对流程有了很好的了解。这是一种客户端/服务器交互,在 Erlang 代码和连接到端口的一些外部客户端之间。但是在 Erlang 系统中,Erlang 进程之间也存在客户端/服务器关系,双方都在运行 Erlang 代码。 (即使只是 gen_server 进程和 Erlang 命令 shell 进程。)
当您使用 gen_server:call/cast 客户端函数时,它们会以您从未见过的方式包装您的消息,但接收的 gen_server 进程会识别这一点并使用它对消息进行分类,然后将解包的消息传递给相应的 handle_call/handle_cast。除此之外,流程与 tcp 端口上的传入数据相同:在这两种情况下,它只是到服务器的异步消息,被接收并分派(dispatch)到正确的函数。同时在客户端, gen_server:call() 函数将等待回复(发送者的 Pid 包含在包装器中),而 gen_server:cast() 立即继续。
这些实际上只是便利功能。原则上, gen_server 可能只有一个回调来处理各种消息,让你来编码它是调用还是强制转换以及如何使用react。但是通过提供这些库函数并为您分类消息,它可以降低将调用视为强制转换或反之亦然的风险,或者将带外消息与正确的调用/强制转换混淆。流程在所有情况下都是相同的:客户端 -> 服务器 -> 回调 [ -> 服务器回复 -> 客户端 ]。
因此,您可以使用 ?SERVER !
来实现 get_count() 函数。 ,在您的 handle_info() 回调中而不是在 handle_call() 中处理该消息。 (只是不要忘记将回复发送回消息中包含的 Pid,否则客户端将永远卡住。)
{get_count, self()}
或者您可以完全跳过实现 get_count() 之类的用户 API 函数,并告诉您的用户只需将 {get_count, self()} 发送到服务器进程并等待回复(其形状也必须记录在案)。但是,您以后无法更改这些消息在后台的外观细节。 gen_server:call/cast 函数可帮助您隐藏这些杂乱的实现细节,并降低您搞砸客户端/服务器通信的可能性。
希望这可以帮助。
关于erlang - 难以理解 Erlang Gen_Server 架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43982822/
当看 abcast abcast man page , 和 cast cast man page ,我无法理解这两者之间有什么区别。 有人可以向我澄清这一点。 谢谢 最佳答案 gen_server:c
有人可以解释gen_server:start()和gen_server:start_link()有什么区别吗? 有人告诉我这是关于多线程的东西。 编辑: 如果我的gen_server是从多个线程中调用
我有一个包含数千个条目的 trie(用元组和列表实现),我想支持并发读取。数据的内存占用在 10-20 MB 范围内。 trie 构建一次,之后只读。 维护状态并为客户端提供并发访问的推荐方法是什么?
我想要做的是让 gen_server 进程接受一个新客户端并立即生成一个新子进程来处理下一个。我看到的问题是,当套接字完成并因此终止时,它也会关闭监听套接字,即使它不再引用它,我也无法弄清楚原因。 知
我有一个主管启动了许多 gen_server。每个 gen_server 都有大量的数据负载,这需要很多时间。我想知道什么时候发生错误,存储在 gen_server 状态及其进程 dict 中的数据是
我尝试将消息转换到 gen_server: gen_server:cast({global, ID}, {watchers}). 处理程序是: handle_cast({watchers}, Sta
我需要编写一个服务器,它将接收来自其他模块的指令并根据收到的指令采取行动。效率是我主要关心的问题。我也用 gen_server还是我自己写服务器。 “我自己的服务器”是指: -module(myser
unregister_name({local,Name}) -> _ = (catch unregister(Name)); unregister_name({global,Name}) ->
免责声明:作者是 OTP 的新手,对 Erlang 的语法、流程和消息有一些基本的了解。 我试图掌握 Erlang 中行为的概念,但我脑海中浮现出许多问题,使我无法理解像 gen_server 这样的
在我的 gen_server 中,我将这样终止它: handle_info({'EXIT', _From, _Reason}, State) -> {stop, partner_fled, S
我想延长 gen_server (创建一个 gen_server_extra )具有一些附加功能。要求是: gen_server_extra进程的行为应该像常规的 gen_server的。例如,他们应
我一直在尝试使用 erlang:monitor/2 来监视 gen_server。不幸的是,每次我尝试这个时,Erlang shell 都会进入无限循环。 这是我为测试这一点而编写的测试程序。 -mo
美好的一天, 我有一个 gen_server 进程,它定期执行一些长时间运行的状态更新任务handle_info: handle_info(trigger, State) -> NewStat
我的 gen_server 包含这样的方法: handle_call(error, From, State) -> io:format("Inside the handle_call erro
我有创建其他主管的根主管: start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) ->
我有 gen_server: start(UserName) -> case gen_server:start({global, UserName}, player, [], []) of
有没有办法告诉 gen_server:“主管已初始化所有 gen_servers,现在您可以发送消息”? 我有一个 worker gen_server,他的工作是在他的监督树中设置其他 gen_ser
我有一个gen_server进程注册了这样的全局名称: global:register_name(>, self()), 另一个进程正在尝试使用gen_server:call向该进程发送消息,如下所示
我正在尝试学习 Erlang 和 OTP,因此我目前正在尝试掌握 gen_server。 我编写了一个快速的 gen_server 实现: -module(test). -behavior(gen_s
Erlang 文档说明了有关 gen_servers 的以下内容: ... Note that for any other reason than normal, shutdown, or {shut
我是一名优秀的程序员,十分优秀!