我有一个gen_server模块,可以在客户端进程发送数据时将数据记录到文件中。当两个客户端进程同时向此模块发送数据时会发生什么?文件操作是否会相互冲突? erlang documentation在这里令人沮丧地不清楚。
答案 0 :(得分:13)
每个Erlang进程都维护一个消息队列。该过程将获取消息并逐个处理消息。
在您的示例中,如果两个客户端同时调用gen_server
,则这些调用将成为gen_server
进程队列中的消息,gen_server
将处理这些消息逐一。所以不必担心冲突。
但如果一个进程必须处理来自其他进程的过多消息,则需要考虑进程的容量并优化设计,否则它将成为瓶颈。
答案 1 :(得分:5)
gen_server在与客户端进程分开的进程中运行,因此当您对其进行调用/强制转换时,实际上是向服务器进程发送消息。所有消息都放在进程消息队列中,进程逐个处理它们的消息。如果在进程繁忙时消息到达,则将其放入消息队列中。因此,同时到达的日志消息将永远不会相互干扰,因为它们将按顺序处理。
这不是gen_server的属性,而是erlang中所有进程的一般属性,这就是为什么在gen_server文档中没有提到这一点。
答案 2 :(得分:0)
gen_server只按处理顺序处理请求,无论是从一个进程还是多个进程完成的。
如果写入日志,没有理由担心竞争条件。
答案 3 :(得分:0)
幸运的是,OTP的源代码随时可以在github获得,但简短的回答是gen_server在循环中运行,按顺序回复请求,没有一种类型的优先级(handle_cast,handle_call或handle_info) )而不是另一个。
使用handle_call可能是一个问题,因为gen_server进程必须在它处理队列中的下一个cast / call / info之前返回。例如,在handle_call中,避免使用self()!
调用gen_server:call