erlang 当两个客户端同时调用gen_server方法时会发生什么?

m0rkklqb  于 2022-12-08  发布在  Erlang
关注(0)|答案(4)|浏览(164)

我有一个gen_server模块,当一个客户端进程向它发送数据时,它会将数据记录到一个文件中。当两个客户端进程同时向这个模块发送数据时会发生什么?文件操作会相互冲突吗?令人沮丧的是,Erlang文档在这里不清楚。

44u64gxh

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 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.

vqlkdk9b

vqlkdk9b2#

gen_server在与客户端进程分开的进程中运行,因此当您对它执行call/cast时,实际上是在向服务器进程发送消息。
所有的消息都被放置在一个进程的消息队列中,并且进程逐个处理它们的消息。如果消息在进程忙碌时到达,则它被放置在消息队列中。因此,同时到达的日志消息不会相互干扰,因为它们将被顺序处理。
这不是gen_server本身的属性,而是Erlang中所有进程的通用属性,这就是为什么gen_server文档中没有提到这一点。

lskq00tm

lskq00tm3#

gen_server只是按照请求的执行顺序来处理请求,而不管它们是从一个进程还是多个进程执行的。
在写入日志的情况下,没有理由担心竞争条件。

qc6wkl3g

qc6wkl3g4#

幸运的是,OTP的源代码在github上很容易获得,但简单的答案是gen_server在循环中运行,按照接收的顺序回答请求,没有一种类型(handle_cast、handle_call或handle_info)优先于另一种类型的优先级。
使用handle_call可能会有问题,因为gen_server进程必须在处理队列中的下一个cast/call/info之前返回。例如,在handle_call中,避免使用gen_server:call和self()!

相关问题