Tôi chuẩn bị thêm một trình xử lý tín hiệu bổ sung vào một ứng dụng chúng tôi có ở đây và tôi nhận thấy rằng tác giả đã sử dụng sigaction()để thiết lập các trình xử lý tín hiệu khác. Tôi sẽ sử dụng signal(). Để theo quy ước tôi nên sử dụng sigaction()nhưng nếu tôi viết từ đầu, tôi nên chọn cái nào?

chia sẻ | theo dõi
Hoạt động Cũ nhất Hữu ích

Sử dụng sigaction()trừ khi bạn có lý do rất thuyết phục để không làm như vậy.

Bạn đang xem: Posix là gì

Các signal()giao diện có cổ (và vì thế sẵn có) ủng hộ nó, và nó được định nghĩa trong tiêu chuẩn C. Tuy nhiên, nó có một số đặc điểm không mong muốn sigaction()tránh được – trừ khi bạn sử dụng các cờ được thêm vào rõ ràng sigaction()để cho phép nó mô phỏng trung thực signal()hành vi cũ .

Các signal()chức năng không (nhất thiết) chặn các tín hiệu khác từ đến khi xử lý hiện nay đang thực hiện; sigaction()có thể chặn các tín hiệu khác cho đến khi trình xử lý hiện tại trở lại. Các signal()chức năng (thường) resets các hành động tín hiệu trở lại SIG_DFL(mặc định) cho hầu hết các tín hiệu. Điều này có nghĩa là signal()trình xử lý phải tự cài đặt lại như là hành động đầu tiên của nó. Nó cũng mở ra một cửa sổ dễ bị tổn thương giữa thời điểm tín hiệu được phát hiện và trình xử lý được cài đặt lại trong đó nếu một trường hợp thứ hai của tín hiệu đến, hành vi mặc định (thường chấm dứt, đôi khi có thành kiến ​​- còn gọi là kết xuất lõi). Hành vi chính xác của signal()các hệ thống khác nhau – và các tiêu chuẩn cho phép các biến thể đó.

Đây thường là những lý do tốt để sử dụng sigaction()thay vì signal(). Tuy nhiên, giao diện của sigaction()không thể phủ nhận là khó sử dụng hơn.

Cho dù hai bạn sử dụng, không bị cám dỗ bởi các giao diện tín hiệu thay thế chẳng hạn như sighold(), sigignore(), sigpause()và sigrelse(). Chúng là những lựa chọn thay thế trên danh nghĩa sigaction(), nhưng chúng chỉ được chuẩn hóa và hầu như không có trong POSIX để tương thích ngược hơn là sử dụng nghiêm túc. Lưu ý rằng tiêu chuẩn POSIX cho biết hành vi của họ trong các chương trình đa luồng là không xác định.

Các chương trình và tín hiệu đa luồng là một câu chuyện phức tạp khác. AFAIK, cả hai signal()và sigaction()đều ổn trong các ứng dụng đa luồng.

Xem thêm: Curriculum Vitae Là Gì

Cornstalks quan sát :

Trang người dùng Linux cho signal()biết:

  Các ảnh hưởng của signal()trong một quy trình đa luồng là không xác định.

Vì vậy, tôi nghĩ sigaction()là duy nhất có thể được sử dụng một cách an toàn trong một quy trình đa luồng.

Nó thật thú vị. Trang hướng dẫn Linux hạn chế hơn POSIX trong trường hợp này. POSIX chỉ định cho signal():

Nếu quy trình là đa luồng hoặc nếu quy trình là đơn luồng và trình xử lý tín hiệu được thực thi khác với kết quả của:

Việc kêu gọi quá trình abort(), raise(), kill(), pthread_kill(), hoặc sigqueue()để tạo ra một tín hiệu mà không bị chặn Một tín hiệu đang chờ xử lý được bỏ chặn và được gửi trước khi cuộc gọi được bỏ chặn nó trả về

hành vi không được xác định nếu trình xử lý tín hiệu tham chiếu đến bất kỳ đối tượng nào ngoài errnothời lượng lưu trữ tĩnh ngoài việc gán giá trị cho đối tượng được khai báo là volatile sig_atomic_thoặc nếu trình xử lý tín hiệu gọi bất kỳ chức năng nào được xác định trong tiêu chuẩn này ngoài một trong các chức năng được liệt kê trong Khái niệm tín hiệu .

Vì vậy, POSIX chỉ định rõ hành vi của signal()một ứng dụng đa luồng.

Xem thêm: Tỉnh Ủy Tiếng Anh Là Gì – Huyện Ủy Trong Tiếng Tiếng Anh

Tuy nhiên, về cơ bản, sigaction()được ưu tiên trong mọi trường hợp – và mã đa luồng di động nên sử dụng sigaction()trừ khi có lý do áp đảo tại sao nó không thể (chẳng hạn như “chỉ sử dụng các hàm được xác định bởi Tiêu chuẩn C” – và có, mã C11 có thể là đa -đọc). Đó là cơ bản những gì đoạn mở đầu của câu trả lời này cũng nói.

Chuyên mục: Hỏi Đáp