Every Erlang process maintains a message queue. The process will fetch a message and handle the messages one by one. In your example, if two clients calls the gen_server at the same time, these calls will become a message in the queue of gen_server process, and the gen_server will process these messages one by one. So no need to worry about a conflict. But if one process has to handle too many messages from other processes, you'll need to think about the capacity of the process and optimize the design, or else it will become a bottleneck.
4条答案
按热度按时间44u64gxh1#
Every Erlang process maintains a message queue. The process will fetch a message and handle the messages one by one.
In your example, if two clients calls the
gen_server
at the same time, these calls will become a message in the queue ofgen_server
process, and thegen_server
will process these messages one by one. So no need to worry about a conflict.But if one process has to handle too many messages from other processes, you'll need to think about the capacity of the process and optimize the design, or else it will become a bottleneck.
vqlkdk9b2#
gen_server
在与客户端进程分开的进程中运行,因此当您对它执行call
/cast
时,实际上是在向服务器进程发送消息。所有的消息都被放置在一个进程的消息队列中,并且进程逐个处理它们的消息。如果消息在进程忙碌时到达,则它被放置在消息队列中。因此,同时到达的日志消息不会相互干扰,因为它们将被顺序处理。
这不是
gen_server
本身的属性,而是Erlang中所有进程的通用属性,这就是为什么gen_server文档中没有提到这一点。lskq00tm3#
gen_server只是按照请求的执行顺序来处理请求,而不管它们是从一个进程还是多个进程执行的。
在写入日志的情况下,没有理由担心竞争条件。
qc6wkl3g4#
幸运的是,OTP的源代码在github上很容易获得,但简单的答案是gen_server在循环中运行,按照接收的顺序回答请求,没有一种类型(handle_cast、handle_call或handle_info)优先于另一种类型的优先级。
使用handle_call可能会有问题,因为gen_server进程必须在处理队列中的下一个cast/call/info之前返回。例如,在handle_call中,避免使用gen_server:call和self()!