2010-04-06 177 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