【发布时间】:2016-10-13 18:11:50
【问题描述】:
我有一个关于 Erlang 中的跟踪器的问题,以及如何在不丢失任何跟踪事件的情况下打开和关闭这些跟踪器。假设我有一个进程 P1 正在使用 send 和 receive 跟踪标志进行跟踪,如下所示:
erlang:trace(P1Pid, true, [set_on_spawn, send, 'receive', {tracer, T1Pid}])
由于指定了 set_on_spawn 标志,一旦 P1 生成(子)进程 P2,相同的标志(ie set_on_spawn、send、'receive')将也适用于 P2。现在假设我想在 P2 上创建一个新的跟踪器,以便跟踪器 T1 处理来自 P1 的跟踪,而跟踪器 T2 处理来自 P2 的跟踪。为此,(因为 Erlang 只允许每个进程使用一个跟踪器),我需要首先从 P2 取消设置跟踪标志(ie set_on_spawn、send、'receive')(因为这些是由于set_on_spawn标志而自动继承的)并在P2上再次设置它们,如下所示:
% Unset trace flags on P2.
erlang:trace(P2Pid, false, [set_on_spawn, send, 'receive']),
% We might lose trace events at this instant which were raised
% by process P2 while un-setting the tracer on P2 and setting
% it again.
% Now set again trace flags on P2, directing the trace to
% a new tracer T2.
erlang:trace(P2Pid, true, [set_on_spawn, send, 'receive', {tracer, T2Pid}]),
在设置和取消设置跟踪器之间的行中,进程 P2 引发的一些跟踪事件可能会由于这里的竞争条件而丢失。
我的问题是:这可以在不丢失跟踪事件的情况下实现吗?
Erlang 是否提供了可以以原子方式完成这种“跟踪器切换”(即从 T1 到 T2)的方法?
或者,是否可以暂停 Erlang VM 并在此过程中暂停跟踪,从而避免丢失跟踪事件?
【问题讨论】: