我想在linux 2.6+中使用支持NPTL的libc的多线程进程中使用setitimer()
(或者更不可能,alarm()
)。哪个线程将从内核收到sigalarm (SIGALRM)
?
感谢。
2014-04更新:如果我想编写像gperftools的cpuprofile这样的分析实用程序,我应该如何在多线程程序中设置setitimer()
;但在我的工具中,我想支持两个动态链接的程序(因此可以将自己的库注入init初始化)和静态链接的程序(不可能做^^^^^^)。
我当前的分析工具可以在setitimer
之后和fork()
之前设置exec()
,并且还使用ptrace
来控制目标程序并劫持SIGPROF由setitimer
生成的/ SIGVPROF / SIGALRM。我不知道它如何与多线程程序一起使用。
答案 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)。