【问题标题】:How to properly handle signals, so that gperftools CPU profiler still works?如何正确处理信号,让 gperftools CPU profiler 仍然有效?
【发布时间】:2013-10-25 05:52:45
【问题描述】:

我想分析我的守护程序,它会暂停主线程:

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

int sig;
sigwait(&signal_mask, &sig);

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

env CPUPROFILE=daemon.prof ./daemon

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

【问题讨论】:

  • 我正在“提高”你的问题,因为它提出了一个重要的问题 w.r.t.信号处理。

标签: c++ multithreading signals profiler gperftools


【解决方案1】:

所有其他线程只是阻塞所有信号。

您只需要在所有线程(或您要分析的线程)中取消阻止SIGPROF。我们只是在多线程守护进程中解决完全相同的问题。

【讨论】:

    【解决方案2】:

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

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

    事实上,查看 signal(2) 手册页:

    The effects of signal() in a multithreaded process are unspecified.
    

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

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

    您也可以尝试使用pthread library's sigmask wrapper pthread_sigmask,,但我不清楚它在子线程从 sigmask 中删除条目(pthread 继承其父 pthread sigmask)等情况下的效果如何。

    【讨论】:

    • 至少在Linux中,有两种信号,进程范围的(发送到任何线程)和per-pthread(可以直接发送信号到特定线程)。仍然不知道,setitimer(发送 SIGPROF/SIGALRM)(my own question)使用了哪种信号。更新:主题groups.google.com/forum/#!topic/linux.kernel/DF-VwEf2AqEsetitimer 使用了每线程信号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 2013-10-10
    • 1970-01-01
    • 2020-04-01
    • 2015-01-28
    • 2017-09-25
    相关资源
    最近更新 更多