设置计时器、SIGALRM 和多线程进程(linux,c)
我想在带有支持 NPTL 的 libc 的 linux 2.6+ 的多线程进程中使用 setitimer()
(或者可能性较小的 alarm()
)。哪个线程将从内核接收sigalarm (SIGALRM)
?
谢谢。
2014-04 更新:如果我想编写像 gperftools 的 cpuprofile 这样的分析实用程序,我应该如何在多线程程序中设置 setitimer()
;但在我的工具中,我想支持动态链接程序(因此可以将我自己的库注入到初始化分析中)和静态链接程序(无法执行^^^^^^)。
我当前的分析工具可以在 fork()
之后和 exec()
之前设置 setitimer
,并且还使用 ptrace
code> 来控制目标程序并劫持由 setitimer
生成的 SIGPROF/SIGVPROF/SIGALRM。我不知道它如何与多线程程序一起工作。
I want to use setitimer()
(or less probable, the alarm()
) in multithreaded process in linux 2.6+ with NPTL-enabled libc. Which thread will receive sigalarm (SIGALRM)
from kernel?
Thanks.
2014-04 update: How should I set the setitimer()
in multithreaded program, if I want to write a profiling utility like gperftools's cpuprofile; but in my tool I want to support both dynamically linked programs (so it is possible to inject my own library to init profiling) and statically linked programs (without the possibility of doing ^^^^^^).
My current profiling tool works with setting setitimer
just after fork()
and before exec()
, and it also uses ptrace
to get control over the target program and to hijack SIGPROF/SIGVPROF/SIGALRM generated by the setitimer
. I have no exact idea how it works with multithreaded programs.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
来自 signal(7) 手册页:
现在, alarm(2) 手册页显示:
因此,信号被传递到进程(信号也可能指向某个线程),因此您不知道哪个线程将接收它。
与 setitimer(2) 相同:
您可以在除一个线程之外的所有线程中阻止
SIGALARM
,然后您可以确定它将被传递到唯一的线程。假设您使用 pthread,您可以使用 pthread_sigmask() 阻止信号。From signal(7) man page:
Now, alarm(2) man page says that:
So, the signal is delivered to a process (a signal might be directed at certain thread too) and thus you do not know which of the threads will receive it.
The same with setitimer(2):
You could block
SIGALARM
in all your threads except one, then you could be certain that it will be delivered to that only thread. Assuming you are using pthreads, you can block signals with pthread_sigmask().2010 年 LKML 有一个有趣的话题 https://lkml.org/lkml/2010/4 /11/81:“setitimer 与线程:SIGALRM 返回到哪个线程?(进程主进程或单个子进程)”,作者:Frantisek Rysanek (cz)。作者表示
setitimer
至少在 Fedora 5 之前使用了每线程信号:但在最近的 Fedora 中,行为发生了变化(“man pthreads”,...“线程不共享间隔计时器(在内核 2.6.12 中修复)。”)
在该主题中,Andi Kleen ( Intel) 建议切换到“POSIX 计时器 (
timer_create
)";在 ML 线程中,Davide Libenzi 建议使用timerfd
(timerfd_create、timerfd_settime)在非古老的 Linux 上。There was interesting topic in LKML in 2010 https://lkml.org/lkml/2010/4/11/81: "setitimer vs. threads: SIGALRM returned to which thread? (process master or individual child)" by Frantisek Rysanek (cz). Author says that
setitimer
used per-thread signals at least in times before Fedora 5:But in more recent Fedoras the behavior was changed ("man pthreads", ..."Threads do not share interval timers (fixed in kernel 2.6.12).")
In the topic, Andi Kleen (Intel) recommends to switch to "POSIX timers (
timer_create
)"; and in ML thread Davide Libenzi suggests use oftimerfd
(timerfd_create, timerfd_settime) on non-ancient Linuxes.我读过很多帖子,但我还没有找到信号到底是如何工作的。我通常使用pause()来等待信号。但这不起作用,因为无法排除 SIGALARM 并且pause() 不返回信号。这就是为什么它只适用于 sigwait。经过几次尝试,我想出了这个解决方案。
I've read many posts but I haven't found how the signals work exactly. I usually use pause() to wait for a signal. But that doesn't work because SIGALARM can't be excluded and pause() doesn't return a signal. That's why it only works with sigwait. After a few tries I came up with this solution.