Приостановка процессов Erlang - PullRequest
0 голосов
/ 28 сентября 2019

Я отслеживаю процесс Эрланга, скажем, P, вызывая BIF erlang:trace(Pid_P, true, [set_on_spawn, procs, send, 'receive']) из какого-то процесса.Согласно документам Erlang, последний процесс становится трассировщиком для P, который я назову Trc_Q.

Предположим, что этот процесс P порождает новый процесс Q.Поскольку флаг set_on_spawn был указан при вызове erlang:trace/3 выше, Q будет автоматически отслеживаться также Trc_P.


Я хочу создать new tracer, Trc_Q и передать ему владение трассировкой Q, чтобы полученная конфигурация соответствовала процессу P, отслеживаемому трассировщиком Trc_P, Q на Trc_Q.

Однако Erlang допускает максимум один трассировщик на процесс, поэтому я не могу достичь указанной конфигурации, вызывая erlang:trace(Pid_Q, true, ..) из Trc_Q.Единственный возможный способ - сделать это в два шага:

  1. Tracer Trc_Q вызывает erlang:trace(Pid_Q, false, ..), чтобы остановить Trc_P от отслеживания Q;
  2. Trc_Q вызововerlang:trace(Pid_Q, true, ..) снова, чтобы начать трассировку Q.

В промежуток времени между шагами 1. и 2. выше, возможно, чтотрассировка событий по процессу Q потеряна , потому что в этот момент нет прикрепленного трассировщика.Один из способов смягчить это - выполнить следующее:

  1. Приостановить процесс Q, вызвав erlang:suspend_process(Pid_Q) с Trc_Q (обратите внимание, что согласно документам Erlang, Trc_Q остается заблокированным до Q в конечном итоге приостанавливается виртуальной машиной);
  2. Trc_Q вызывает erlang:trace(Pid_Q, false, ..), чтобы остановить Trc_P от трассировки Q;
  3. Trc_Q снова вызывает erlang:trace(Pid_Q, true, ..), чтобы начать трассировкуQ;
  4. Наконец, Trc_Q вызывает erlang:resume_process(Pid_Q), чтобы Q мог продолжить выполнение.

Из того, что я смог выяснить, пока QПриостановлено, сообщения, отправленные на него, ставятся в очередь, и при возобновлении Trc_Q получает события трассировки {trace, Pid_Q, receive, Msg} соответственно без каких-либо потерь.

У меня есть одно ограничение, которое заставило меня взглянуть на процесс приостановки / возобновления: я не могу изменить код P или Q, поэтому вставка выражений receive для блокировки указанных процессов исключена.

Однако я не решаюсь использовать приостановку / возобновление, поскольку в документах Erlang прямо сказано, что они должны использоваться только для целей отладки .Есть идеи, почему это так?

...