setitimer,SIGALRM&多线程进程(linux,c)

时间:2010-04-06 17:28:47

标签: linux multithreading linux-kernel profiling signals

我想在linux 2.6+中使用支持NPTL的libc的多线程进程中使用setitimer()(或者更不可能,alarm())。哪个线程将从内核收到sigalarm (SIGALRM)

感谢。

2014-04更新:如果我想编写像gperftools的cpuprofile这样的分析实用程序,我应该如何在多线程程序中设置setitimer();但在我的工具中,我想支持两个动态链接的程序(因此可以将自己的库注入init初始化)和静态链接的程序(不可能做^^^^^^)。

我当前的分析工具可以在setitimer之后和fork()之前设置exec(),并且还使用ptrace来控制目标程序并劫持SIGPROF由setitimer生成的/ SIGVPROF / SIGALRM。我不知道它如何与多线程程序一起使用。

2 个答案:

答案 0 :(得分:14)

来自signal(7)手册页:

  

过程导向信号可能是   交付给任何一个线程   目前没有   信号受阻。如果不止一个   线程信号未被阻塞,   然后内核选择一个任意的   提供信号的线程。

现在,alarm(2)手册页说:

  

alarm()安排SIGALRM信号   交付给过程   秒秒。

因此,信号被传递到进程(信号也可能被定向到某个线程),因此您不知道哪个线程会接收它。

setitimer(2)相同:

  

当任何计时器到期时,信号为   发送到进程和计时器   (可能)重启。

您可以在除了一个之外的所有线程中阻止SIGALARM,然后您可以确定它将被传递到该唯一的线程。假设您正在使用pthread,则可以使用pthread_sigmask()阻止信号。

答案 1 :(得分:6)

2010年LKML中有一个有趣的话题https://lkml.org/lkml/2010/4/11/81:" setitimer vs. threads:SIGALRM返回哪个线程? (流程主人或个别孩子)"作者:Frantisek Rysanek(cz)。作者说,setitimer至少在Fedora 5之前使用每线程信号:

  

... setitimer()具有每线程粒度。它曾经从计时器传递SIGALRM到称为setitimer()的特定线程。

但是在最近的Fedora中,行为发生了变化(" man pthreads",..."线程不共享间隔定时器(在内核2.6.12中修复)。&# 34;

在主题中,Andi Kleen(英特尔)recommends to switch to" POSIX计时器(timer_create&#34 ;;在ML thread Davide Libenzi建议在非古老的Linux上使用timerfd(timerfd_create,timerfd_settime)。