2011-11-15 8 views
6

Vì vậy, tôi có một vấn đề thiết kế thú vị. Tôi đang làm việc trên SLES 9+ Linux, kernel 2.6+ và có một ứng dụng đa luồng hoạt động như một máy khách RPC. Ý tưởng là có một vài luồng để xử lý các yêu cầu; một yêu cầu như vậy là bắt đầu một "công việc" như một tiến trình con.Chủ đề, tín hiệu và xử lý trẻ em: Thật là một thế giới ... Thật là một thế giới

Bây giờ vấn đề tôi đang gặp phải là thiết lập trình xử lý tín hiệu thích hợp để xử lý nhiều tín hiệu khác nhau. Những gì tôi đã làm là thiết lập một luồng khác để xử lý tín hiệu đang ở trạng thái sigwait() trong khi chặn tất cả các tín hiệu liên quan trong các chủ đề khác. Ý tưởng là tất cả các tín hiệu cho quá trình sẽ được gửi đến chuỗi xử lý tín hiệu và phần còn lại của chủ đề chỉ nên lo lắng về các yêu cầu xử lý khi chúng đến.

Tất cả điều này đều tuyệt vời ngoại trừ những đứa trẻ thối rữa, luôn luôn ném Frisbees của họ trong sân sau của tôi và chà đạp trên tất cả các bãi cỏ của tôi ... nhưng trong tất cả các mức độ nghiêm trọng, xử lý tín hiệu của tôi không nhận được tín hiệu SIGCHLD. Suy đoán tốt nhất của tôi về những gì đang xảy ra ở đây là bởi vì chuỗi truyền tín hiệu không phải là chủ đề sinh ra đứa trẻ, nó sẽ không phải là luồng nhận SIGCHLD, mà thay vào đó là chuỗi công việc của tôi.

Vì vậy, như đối với câu hỏi của tôi:

  1. Tôi phát điên lên vì SIGCHLD không làm cho nó vào chủ đề xử lý tín hiệu của tôi?
  2. Nếu tôi không điên (đó là một căng, tôi biết), làm thế nào bạn sẽ đi về sửa chữa vấn đề này ít? Hiện tại những gì tôi đang làm là thiết lập một trình xử lý tín hiệu rất đơn giản cho SIGCHLD được thiết lập trên tất cả các luồng chỉ đơn giản gửi lại tín hiệu như tín hiệu SIGUSR2 đến nhóm xử lý bị chặn trong tất cả các luồng cho phép xử lý tín hiệu. có vẻ như để làm việc, tuy nhiên tôi không thể không nghĩ rằng tôi đang thiếu một cái gì đó HOẶC có một cách tốt hơn để xử lý điều này ... anh ấy, nhận được nó, xử lý this ... okay ' ll dừng tại

As per David Schwartz request SLES9: NPTL 2.3.5, SLES10: NPTL2.4

+0

Tôi không rõ lý do tại sao bạn muốn một luồng khác xử lý tín hiệu. Nó sẽ được hệ điều hành gọi là không đồng bộ.Nếu có một loạt các công việc phải được thực hiện trong trình xử lý, sau đó tôi sẽ viết một trình xử lý đơn giản, nhanh chóng mà ném một semaphore và đặt ra các sợi công nhân. – EdH

+0

Bạn không điên. Một tín hiệu có thể được xử lý bởi * bất kỳ * thread mà không có tín hiệu bị chặn. – nos

+4

"Thật là một thế giới" không thực sự mô tả vấn đề. –

Trả lời

2

(Edit: Bởi vì tôi không thể đọc được và bạn đã làm pthread_sigmask thích gọi ....)

Trong kernel 2.6, khi SIGCHLD được thiết lập để bỏ qua/SIG_IGN hạt nhân sẽ gặt hái tiến trình con cho bạn. Có vẻ như bạn đã thiết lập một trình xử lý cụ thể cho SIGCHLD cho chuỗi xử lý tín hiệu của bạn để tránh SIGCHLD được đặt thành SIG_IGN/SIG_DFL.

Chỉnh sửa (từ nhận xét): Tôi nghĩ bạn đã gặp phải trường hợp cạnh. Nếu bạn để nó như SIG_IGN trong thread sinh ra các phần tử con, kernel sẽ không gửi SIGCHLD. Nhưng nếu bạn đặt nó để được xử lý, sau đó xử lý của bạn được gọi là thay thế. Tôi nghĩ rằng nếu bạn thiết lập một xử lý nhưng sau đó vẫn chặn tín hiệu trong pthread_sigmask, tín hiệu sẽ được gửi đến một sợi không có tín hiệu bị chặn (thread sigwait của bạn).

+0

Mặc định là để thiết lập để SIG_IGN, tuy nhiên tôi đã cố gắng thêm SIGCHLD vào sigmask thông qua trong pthread_sigmask và chờ đợi trên nó. Vấn đề tôi thấy là rằng tín hiệu SIGCHLD không được gửi đến thread chuyển giao tín hiệu mà thay vào đó dường như được gửi ** CHỈ ** cho chủ đề sinh ra đứa trẻ. Các công việc xung quanh tôi có tại chỗ là có thread cha vấn đề một SIGUSR2 cho nhóm quá trình khi nó được SIGCHLD mà xử lý tín hiệu nhận và giải thích như một đứa trẻ đã hoàn thành và hành động phù hợp – Bob9630

+0

Tôi nghĩ rằng bạn nhấn một trường hợp cạnh. Nếu bạn để nó như SIG_IGN trong thread sinh ra các phần tử con, kernel sẽ không gửi SIGCHLD. Nhưng nếu bạn đặt nó để được xử lý, sau đó xử lý của bạn được gọi là thay thế. Tôi tự hỏi nếu bạn thiết lập một xử lý nhưng sau đó vẫn chặn tín hiệu trong pthread_sigmask, sẽ làm việc? – SoapBox

+0

Thật kỳ quặc, tôi đoán bằng cách buộc một trình xử lý tín hiệu (trong trường hợp của tôi, tôi chỉ đơn giản sử dụng một cái cuống), chúng ta "unignore" tín hiệu, tuy nhiên kể từ khi SIGCHLD vẫn bị chặn trong tất cả các chủ đề, do mặt nạ tín hiệu, nó gió lên được gửi đến bộ xử lý tín hiệu hiện đang trong 'sigwait()', vì vậy nó nhận được tín hiệu như tôi muốn tất cả cùng. Làm ơn cho tôi và thêm câu trả lời của bạn sau những gì bạn đã có trong phần trả lời và tôi sẽ tiếp tục và chấp nhận câu trả lời đó. Cảm ơn! – Bob9630

1

Biên dịch và chạy mã này với khoảng các tùy chọn biên dịch tương tự như bạn sử dụng để xây dựng chương trình của bạn:

#include <pthread.h> 
#include <stdio.h> 
#include <unistd.h> 
int main(void) 
{ 
    char buf[512]; 
    confstr(_CS_GNU_LIBPTHREAD_VERSION, buf, 500); 
    printf("%s\n", buf); 
} 

This announcement không phải là khá rõ ràng về việc NPTL tàu với SLES 9 và, nếu như vậy, nếu đó là mặc định. Nhưng đặt cược của tôi là bạn đang sử dụng LinuxThreads mà không có khả năng nhắm mục tiêu một tín hiệu cho một quá trình.

+0

Anh ấy đã đề cập đến Linux 2.6 ...? – cnicutar