pthreads(7)
mô tả rằng POSIX.1 yêu cầu tất cả các luồng trong một thuộc tính chia sẻ quy trình, bao gồm:
POSIX.1 cũng yêu cầu một số thuộc tính phải khác biệt cho từng luồng, bao gồm:
Quy complete_signal
trình của nhân Linux có khối mã sau - các nhận xét khá hữu ích:
/*
* Now find a thread we can wake up to take the signal off the queue.
*
* If the main thread wants the signal, it gets first crack.
* Probably the least surprising to the average bear.
*/
if (wants_signal(sig, p))
t = p;
else if (!group || thread_group_empty(p))
/*
* There is just one thread and it does not need to be woken.
* It will dequeue unblocked signals before it runs again.
*/
return;
else {
/*
* Otherwise try to find a suitable thread.
*/
t = signal->curr_target;
while (!wants_signal(sig, t)) {
t = next_thread(t);
if (t == signal->curr_target)
/*
* No thread needs to be woken.
* Any eligible threads will see
* the signal in the queue soon.
*/
return;
}
signal->curr_target = t;
}
/*
* Found a killable thread. If the signal will be fatal,
* then start taking the whole group down immediately.
*/
if (sig_fatal(p, sig) &&
!(signal->flags & SIGNAL_GROUP_EXIT) &&
!sigismember(&t->real_blocked, sig) &&
(sig == SIGKILL || !p->ptrace)) {
/*
* This signal will be fatal to the whole group.
*/
Vì vậy, bạn thấy rằng bạn chịu trách nhiệm về nơi các tín hiệu được phân phối:
Nếu quy trình của bạn đã đặt vị trí của tín hiệu thành SIG_IGN
hoặc SIG_DFL
, thì tín hiệu đó sẽ bị bỏ qua (hoặc mặc định - kill, core, hoặc ignore) đối với tất cả các luồng.
Nếu quy trình của bạn đã thiết lập bố trí tín hiệu thành một quy trình xử lý cụ thể, thì bạn có thể kiểm soát luồng nào sẽ nhận tín hiệu bằng cách sử dụng mặt nạ tín hiệu luồng cụ thể pthread_sigmask(3)
. Bạn có thể chỉ định một luồng để quản lý tất cả chúng hoặc tạo một luồng cho mỗi tín hiệu, hoặc bất kỳ hỗn hợp nào của các tùy chọn này cho các tín hiệu cụ thể hoặc bạn dựa vào hành vi mặc định hiện tại của nhân Linux là phân phối tín hiệu đến luồng chính.
Tuy nhiên, một số tín hiệu đặc biệt theo signal(7)
trang người đàn ông:
Một tín hiệu có thể được tạo (và do đó đang chờ xử lý) cho toàn bộ quá trình (ví dụ: khi được gửi bằng kill (2) ) hoặc cho một chuỗi cụ thể (ví dụ: một số tín hiệu nhất định, chẳng hạn như SIGSEGV và SIGFPE, được tạo ra như một hệ quả của việc thực thi một hướng dẫn ngôn ngữ máy cụ thể được hướng tới luồng, cũng như các tín hiệu được nhắm mục tiêu đến một luồng cụ thể bằng cách sử dụng
pthread_kill (3) ). Một tín hiệu hướng quá trình có thể được gửi đến bất kỳ một trong các luồng hiện không bị chặn tín hiệu. Nếu nhiều hơn một trong các luồng có tín hiệu được bỏ chặn, thì hạt nhân sẽ chọn một luồng tùy ý để phân phối tín hiệu.