我试图了解erlang:trace_delivered/1
的确切语义,以确定此功能是否可以适当地用于解决我当前面临的问题。问题如下。
假设有一个跟踪进程X
,一个跟踪程序Y
跟踪X
,以及第三个进程Z
。跟踪器Y
最初正在跟踪X
。流程Z
的任务是通过调用Y
来阻止X
跟踪erlang:trace(X, false)
。 Z
正在运行时,此呼叫任意进行。此后,X
还将向跟踪器Z
发出一条特殊消息stopped
,该消息向Y
发出信号,通知Y
实际上已阻止Z
进行跟踪Y
。
我想保证特殊的X
消息在所有其他跟踪消息都已经交付到stopped
之后,会被交付到Y
的邮箱。据我所知,Erlang不保证不同进程发送到单个进程的消息顺序。具体来说,在我的情况下,这意味着跟踪器Y
可以接收Y
发出的stopped
由于跟踪{{1 }}。我读到有关Z
的内容,并计划在X
的实现中使用以下代码解决我的问题:
erlang:trace_delivered/1
docs(下面引用)中提供了一个类似的示例:
示例:进程
Z
是Tracee,端口... erlang:trace(X, false), Ref = erlang:trace_delivered(X), receive {trace_delivered, X, Ref} -> Y ! stopped end. ...
是Tracer,进程A
是B
的端口所有者。C
想要在B
退出时关闭C
。为了确保跟踪不会被截断,B
可以在A
退出时调用C
,并在关闭erlang:trace_delivered(A)
之前等待消息A
。
我的示例在两个方面与文档中的示例不同:
{trace_delivered, A, Ref}
知道调用B
之前C
的确切执行点 ;就我而言,我不知道A
被erlang:trace_delivered(A)
调用时X
所在的地方。erlang:trace_delivered(X)
相比,我的流程Z
在调用C
之前关闭了对Z
的跟踪。在这种情况下X
的语义是什么?
erlang:trace_delivered(X)
已收到erlang:trace_delivered/1
,在所有跟踪消息都已传递到跟踪器{trace_delivered, X, Ref}
之后? Z
是否自动跟踪执行迹线Y
的点才能提供上述保证?非常感谢您的帮助!
答案 0 :(得分:1)
您对消息的顺序是正确的。如果进程A
向进程B
发送了多个消息,则将保证它们按顺序到达。如果A
向进程B
和C
发送多条消息,则只能保证每个进程的消息顺序。例如:
A
发送B
消息1 A
发送C
消息2 A
发送B
消息3 A
发送C
消息4 在这种情况下,唯一的保证是B
将在消息3之前接收消息1,而C
将在消息4之前接收消息2。
要回答您的问题:
否,如果在生成其他跟踪事件之前调用erlang:trace_delivered/1
,则这些消息将在以后到达。该文档仅保证先前的跟踪消息在{trace_delivered, ...}
之前发送:
当确保在跟踪erlang:trace_delivered(Tracee)时,Trace到达到达跟踪点的所有跟踪消息时,都将{trace_delivered,Tracee,Ref}消息发送到erlang:trace_delivered(Tracee)的调用者。
erlang:trace_delivered/1
周围的保证始终成立。但这不能保证{trace_delivered, ...}
始终是最后一条消息。