我有一个 gen_server 模块,它在客户端进程发送数据时将数据记录到文件中。当两个客户端进程同时向该模块发送数据时会发生什么?文件操作会不会相互冲突?erlang 文档在这里令人沮丧地不清楚。
4 回答
每个 Erlang 进程都维护一个消息队列。该过程将获取一条消息并一一处理这些消息。
在您的示例中,如果两个客户端gen_server
同时调用,这些调用将成为gen_server
进程队列中的一条消息,并且gen_server
将一一处理这些消息。所以不必担心冲突。
但是如果一个进程必须处理来自其他进程的太多消息,则需要考虑进程的容量并优化设计,否则它将成为瓶颈。
它gen_server
在与您的客户端进程不同的进程中运行,因此当您对其执行call
/cast
时,您实际上是在向服务器进程发送消息。
所有消息都放在一个进程的消息队列中,进程一个接一个地处理它们的消息。如果消息在进程繁忙时到达,则将其放入消息队列中。因此,同时到达的日志消息将永远不会相互干扰,因为它们将按顺序处理。
这不是 erlang 本身的属性,gen_server
而是 erlang 中所有进程的一般属性,这就是为什么在 gen_server 文档中没有提及这一点的原因。
Fortunately, the source for OTP is readily available at github, but the short answer is that gen_server runs in a loop, answering requests in order received, with no priority of one type (handle_cast, handle_call, or handle_info) over another.
Using handle_call can potentially be an issue, as the gen_server process will have to return before it can deal with the next cast/call/info in queue. For example, in a handle_call, avoid gen_server:call with self()!
gen_server just handles requests in the order that they was done, not matter they was done from one process or many.
In case of writing to log there is no reason to worry about race-conditions.