2010-04-06 74 views
11

我想在Linux 2.6+的多线程进程中使用setitimer()(或更少的可能性,alarm()),并使用启用NPTL的libc。哪个线程将从内核接收sigalarm (SIGALRM)setitimer,SIGALRM和多线程进程(linux,c)

谢谢。

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

我目前的分析工具可与正好fork()exec()之前设置setitimer,并且它还采用ptrace,并得到了目标程序的控制和劫持由setitimer产生SIGPROF/SIGVPROF/SIGALRM。我不确切知道它如何与多线程程序一起工作。

+1

对于freebsd和solaris来说是一样的吗? – osgx 2010-04-06 17:55:36

回答

13

signal(7)手册页:

一个过程导向的信号可以 传递到线程 认为目前没有封锁 信号中的任何一个。如果多于一个的线程有信号未被阻塞,那么内核选择一个任意线程来传递信号。

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

报警()安排一个SIGALRM信号 在 秒秒内传递到进程。

因此,信号被传递到过程(信号可能在某些线程执导过),因此你不知道哪个线程会收到它。

同样与setitimer(2)

当任何定时器超时后,一个信号是 发送到进程,并且计时器 (潜在)重新启动。

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

+0

和setitimer呢? – osgx 2010-04-06 17:46:03

+0

所有信号都是一样的。 – nos 2010-04-06 17:49:40

+2

@nos基本上,但是你可以通过'pthread_kill()' – pajton 2010-04-06 18:07:52

4

有在LKML有趣的话题,2010年https://lkml.org/lkml/2010/4/11/81: “setitimer与线程:SIGALRM返回哪个线程(过程主控器或个别儿童)?” 由弗朗齐歇克Rysanek(cz)。作者说,setitimer使用每线程信号至少在时间的Fedora 5之前:

... setitimer()有每个线程粒度。它用于将计时器的SIGALRM传送到称为setitimer()的特定线程。

但在最近的浅顶软呢帽的行为已更改(“人并行线程” ......“线程不共享间隔定时器(固定在内核2.6.12)。”

在主题,Andi Kleen(Intel)recommends to switch toPOSIX定时器(timer_create”;并在ML thread Davide Libenzi建议在非古代Linux上使用timerfd(timerfd_create,timerfd_settime)。

+0

用''setitimer'线程进程'搜索。其他有趣的页面:[Solaris 9](http://www.shrubbery.net/solaris9ab/SUNWdev/MTP/p34.html)“当间隔计时器过期时,根据情况将SIGVTALRM或SIGPROF发送给LWP拥有间隔计时器。“; [Redhat错误142790“setitimer CPU计时器应该是per-process,而不是每个线程”,2004](https://bugzilla.redhat.com/show_bug.cgi?id=142790)“setitimer在单个线程上运行,即使在NPTL POSIX表示它应该是全过程的。“发送恨邮件到POSIX和Roland McGrath(“我的更改现在在Linus的树中... 2.6.12”) – osgx 2014-04-14 01:05:11

+0

带有cpuprofile的Google perftools(gperftools)应该与'setitimer'有相同的问题:https://code.google .com/p/gperftools /“* OS X问题:在多线程程序中,似乎OS X通常会将分析信​​号(从sigitimer())发送到主线程,即使它处于睡眠状态,也不会产生正在执行的线程实际工作*“; https://chromium.googlesource.com/external/gperftools/+/8e188310f7d8732d81b7b04f193f89964b7af6c5/src/profiler.cc - “* TODO:检测setitimer()是否适用于进程中的所有线程。*” – osgx 2014-04-14 01:07:57

+0

HPUX有额外的时间间隔具有定义明确的线程行为的定时器:http://www.polarhome.com/service/man/generic.php?qf=setitimer&type=2&of=HP-UX&sf=2 *“另外... HP-UX提供了在线程的三个线程间隔定时器之后,......信号被传递给线程......“* – osgx 2014-04-14 01:17:19