Bạn không thể tin tưởng rằng mọi tín hiệu được gửi sẽ được gửi đi. Ví dụ, nhân linux "kết hợp" SIGCHLD nếu một quá trình mất nhiều thời gian để xử lý SIGCHLD từ một tiến trình con đã thoát.
Để trả lời một phần câu hỏi khác của bạn, các tín hiệu sẽ được "xếp hàng" bên trong kernel nếu một số tín hiệu khác nhau đến quá ngắn trong một khoảng.
Bạn nên sử dụng sigaction()
để thiết lập trình xử lý tín hiệu với sa_sigaction
thành viên của siginfo_t
, thiết lập sa_mask
thành viên của siginfo_t
đối số một cách cẩn thận. Tôi nghĩ rằng điều này có nghĩa là che giấu tất cả các tín hiệu "asynch" ít nhất. Theo trang hướng dẫn dành cho Linux sigaction()
, bạn cũng sẽ che giấu tín hiệu đang được xử lý. Tôi nghĩ bạn nên đặt sa_flags
thành viên thành SA_SIGINFO, nhưng tôi không thể nhớ tại sao tôi lại có sự mê tín này. Tôi tin rằng điều này sẽ giúp quá trình của bạn trở thành một trình xử lý tín hiệu luôn được thiết lập mà không có điều kiện cuộc đua và một điều kiện không bị gián đoạn bởi hầu hết các tín hiệu khác.
Viết chức năng xử lý tín hiệu của bạn rất, rất cẩn thận. Về cơ bản chỉ cần đặt một biến toàn cục để chỉ ra rằng tín hiệu đã bị bắt và phần còn lại của quá trình xử lý hành động mong muốn cho tín hiệu đó. Tín hiệu sẽ được che dấu trong khoảng thời gian ít nhất theo cách đó.
Ngoài ra, bạn sẽ muốn kiểm tra mã xử lý tín hiệu của mình thật kỹ. Đặt nó trong một quy trình thử nghiệm nhỏ và gửi càng nhiều tín hiệu SIGUSR1 và SIGUSR2 càng tốt, có thể từ 2 hoặc 3 chương trình gửi tín hiệu cho mục đích đặc biệt. Trộn lẫn trong một số tín hiệu khác, sau khi bạn tin rằng mã của bạn có thể xử lý SIGUSR1 và SIGUSR2 nhanh chóng và chính xác. Chuẩn bị tinh thần cho việc gỡ lỗi khó khăn.
Nếu bạn đang sử dụng linux và chỉ linux, bạn có thể nghĩ về việc sử dụng signalfd()
để tạo một mô tả tệp mà bạn có thể select()
hoặc thăm dò để nhận các tín hiệu đó. Sử dụng signalfd()
có thể làm cho việc gỡ lỗi dễ dàng hơn.
signal(2)
gợi ý rõ ràng rằng bạn tránh sự nhầm lẫn này bằng cách sử dụngsigaction(2)
thay thế.