如何正确处理信号,以便gperftools CPU Profiler仍然有效?

aby*_*s.7 5 c++ profiler multithreading signals gperftools

我想描述我的守护程序,它暂停主线程:

sigset_t signal_mask;
sigemptyset(&signal_mask);
sigaddset(&signal_mask, SIGTERM);
sigaddset(&signal_mask, SIGINT);

int sig;
sigwait(&signal_mask, &sig);
Run Code Online (Sandbox Code Playgroud)

所有其他线程只是阻止所有信号.据我所知,探查器使用SIGPROF信号进行操作.如果我使用这样的代码开始分析,则输出.prof文件为空:

env CPUPROFILE = daemon.prof ./daemon

我应该如何正确处理主线程和其他线程中的信号以启用性能分析?或者可能是其他地方的问题?

Mar*_*tos 0

我需要查看您的更多代码,但是您的“所有其他线程只是阻止所有信号”的声明引发了……信号。

您必须记住,大多数系统调用都是在线程概念存在之前创建的。信号处理就是其中之一。因此,当您在任何线程上阻止信号时,所有线程都可能会被阻止。

事实上,请查看 signal(2) 联机帮助页:

The effects of signal() in a multithreaded process are unspecified.
Run Code Online (Sandbox Code Playgroud)

是的,这很令人难过,但这是使用低开销统计采样分析器必须付出的代价。解决这个问题非常简单:只需从信号掩码集中删除 SIGPROF(或 SIGALRM,如果您使用的是 REAL 模式),就可以了。

一般来说,除非绝对必要,否则您不应该在主线程以外的任何其他地方进行进程级信号屏蔽...其中“main”不一定意味着 MAIN() 正在运行的线程,而是相反,您认为该线程是所有其他线程的“老板”,原因您已经说得很清楚了。:)

您还可以尝试使用pthread 库的 sigmask 包装器 pthread_sigmask,但我不清楚它在诸如子线程从 sigmask 中删除条目(pthread 继承其父级的 pthread sigmask)等情况下的工作效果如何。