2010-04-06 8 views
11

Tôi muốn sử dụng setitimer() (hoặc ít có thể xảy ra hơn, alarm()) trong quy trình đa luồng trong linux 2.6+ với libc đã bật NPTL. Chuỗi nào sẽ nhận được sigalarm (SIGALRM) từ hạt nhân?setitimer, SIGALRM & quy trình đa luồng (linux, c)

Cảm ơn.

Cập nhật 2014-04: Tôi nên đặt setitimer() trong chương trình đa luồng, nếu tôi muốn viết một tiện ích lược tả như cpuprofile của gperftools; nhưng trong công cụ của tôi, tôi muốn hỗ trợ cả hai chương trình liên kết động (vì vậy có thể đưa thư viện của riêng tôi vào init profiling) và các chương trình liên kết tĩnh (không có khả năng làm ^^^^^^).

công cụ profiling hiện tại của tôi làm việc với các thiết setitimer ngay sau fork() và trước exec(), và nó cũng sử dụng ptrace để có được quyền kiểm soát các chương trình mục tiêu và để cướp SIGPROF/SIGVPROF/SIGALRM tạo ra bởi các setitimer. Tôi không có ý tưởng chính xác làm thế nào nó hoạt động với các chương trình đa luồng.

+1

cũng đúng cho freebsd và solaris? – osgx

Trả lời

13

Từ trang signal(7) người đàn ông:

Một tín hiệu quá trình định hướng có thể được giao cho bất kỳ một trong những chủ đề rằng hiện không có tín hiệu bị chặn. Nếu nhiều hơn một trong số các luồng có tín hiệu được bỏ chặn, thì hạt nhân chọn một chuỗi tùy ý để phân phối tín hiệu.

Bây giờ, alarm(2) trang người đàn ông nói rằng:

báo động() sắp xếp cho một tín hiệu SIGALRM được gửi đến quá trình trong giây giây.

Vì vậy, tín hiệu được chuyển giao cho một quá trình (một tín hiệu có thể được hướng vào chủ đề nào đó quá) và do đó bạn không biết được trong những chủ đề sẽ nhận được nó.

Cùng với setitimer(2):

Khi bất kỳ timer hết hạn, một tín hiệu là gửi đến quá trình này, và bộ đếm thời gian (khả năng) khởi động lại.

Bạn có thể chặn SIGALARM trong tất cả các chủ đề của mình ngoại trừ một chủ đề, sau đó bạn có thể chắc chắn rằng nó sẽ được gửi đến chỉ chuỗi đó. Giả sử bạn đang sử dụng pthreads, bạn có thể chặn tín hiệu với pthread_sigmask().

+0

và điều gì về setitimer? – osgx

+0

Điều này cũng giống nhau đối với tất cả các tín hiệu. – nos

+2

@nos Về cơ bản, nhưng bạn có thể truyền tín hiệu thẳng đến một số chuỗi nhất định với ví dụ 'pthread_kill()' – pajton

4

Có chủ đề thú vị trong LKML năm 2010 https://lkml.org/lkml/2010/4/11/81: "setitimer vs đề: SIGALRM trở về mà ren (quá trình thạc sĩ hoặc con cá nhân)?" Bởi Frantisek Rysanek (cz). Tác giả nói rằng setitimer sử dụng tín hiệu cho mỗi chủ đề ít nhất là trong lần trước khi Fedora 5:

... setitimer() có độ chi tiết theo chủ đề.Nó được sử dụng để phân phối SIGALRM từ bộ hẹn giờ đến chuỗi cụ thể được gọi là setitimer().

Nhưng trong Fedoras gần đây hành vi này đã được thay đổi ("người đàn ông pthreads", ... "Chủ đề không chia sẻ giờ khoảng (cố định trong kernel 2.6.12).")

Trong chủ đề, Andi Kleen (Intel) recommends to switch to "bộ định thời POSIX (timer_create)"; và trong ML thread Davide Libenzi đề nghị sử dụng timerfd (timerfd_create, timerfd_settime) trên Linux không cổ.

+0

Googled với quy trình chuỗi "setitimer'". Các trang thú vị khác: [Solaris 9] (http://www.shrubbery.net/solaris9ab/SUNWdev/MTP/p34.html) "Khi bộ đếm thời gian hết hạn, hoặc SIGVTALRM hoặc SIGPROF, khi thích hợp, được gửi đến LWP sở hữu bộ đếm thời gian. "; [Redhat lỗi 142790 "bộ đếm thời gian CPU setitimer nên được cho mỗi quá trình, không theo chủ đề", 2004] (https://bugzilla.redhat.com/show_bug.cgi?id=142790) "setitimer hoạt động trên các chủ đề cá nhân, ngay cả dưới NPTL POSIX nói nó nên được xử lý rộng rãi. " Gửi thư ghét đến POSIX và Roland McGrath ("Thay đổi của tôi là trong cây của Linus bây giờ ... 2.6.12") – osgx

+0

Google-perftools (gperftools) với cpuprofile nên có cùng một vấn đề với 'setitimer': https://code.google Vấn đề .com/p/gperftools/"* OS X: trong các chương trình đa luồng, có vẻ như OS X thường cung cấp tín hiệu lược tả (từ sigitimer()) đến luồng chính, ngay cả khi nó đang ngủ, thay vì các luồng được sinh ra đang làm công việc thực tế*"; https://chromium.googlesource.com/external/gperftools/+/8e188310f7d8732d81b7b04f193f89964b7af6c5/src/profiler.cc - "* TODO: Phát hiện có hay không setitimer() áp dụng cho tất cả các chuỗi trong quá trình. *" – osgx

+0

HPUX có khoảng thời gian bổ sung bộ hẹn giờ với hành vi được xác định rõ ràng cho các chủ đề: http://www.polarhome.com/service/man/generic.php?qf=setitimer&type=2&of=HP-UX&sf=2 * "Ngoài ra ... HP-UX cung cấp sau ba bộ định thời khoảng thời gian cho mỗi chủ đề, ... tín hiệu được gửi tới luồng ... "* – osgx