Tại sao tôi không thể giết tiến trình của SIGSTOP bằng SIGTERM và tín hiệu đang chờ xử lý được lưu trữ ở đâu?


24

Tôi đang sử dụng Debian căng (systemd). Tôi đã chạy daemon rsyslog trong foreground bằng cách sử dụng /usr/sbin/rsyslogd -n và tôi đã làm Ctrl+ Zđể dừng nó. Trạng thái của quá trình thay đổi thành Tl(dừng lại, luồng). Tôi đã ban hành nhiều lệnh cho quy trình và trạng thái của quy trình là như nhau : . Khi tôi làm một , nó chết. Tôi có 3 câu hỏi.kill -15 <pid>Tlfg

  • Tại sao SIGSTOPquá trình -ed không đáp ứng SIGTERM? Tại sao kernel giữ nó ở trạng thái tương tự?
  • Tại sao nó bị giết ngay khi nhận được SIGCONTtín hiệu?
  • Nếu đó là do SIGTERMtín hiệu trước đó , nó được giữ ở đâu cho đến khi quá trình được nối lại?

Câu trả lời:


41

SIGSTOPSIGKILLlà hai tín hiệu không thể bị bắt và xử lý bởi một quá trình. SIGTSTPgiống như SIGSTOPngoại trừ việc nó thể bị bắt và xử lý.

Các tín hiệu SIGSTOPSIGTSTPdừng một quá trình trong các bài hát của nó, sẵn sàng cho SIGCONT. Khi bạn gửi quy trình đó a SIGTERM, quy trình không chạy và vì vậy nó không thể chạy mã để thoát.

(Ngoài ra còn có SIGTTINSIGTTOU, đó là các tín hiệu được tạo bởi lớp TTY khi một công việc nền cố gắng đọc hoặc ghi vào thiết bị đầu cuối. Chúng có thể bị bắt nhưng sẽ dừng lại (đình chỉ) quá trình, giống như SIGTSTP. Nhưng bây giờ tôi sẽ đi bỏ qua hai phần còn lại của câu trả lời này.)

Của bạn CtrlZgửi quy trình a SIGTSTP, dường như không được xử lý đặc biệt theo bất kỳ cách nào rsyslogd, do đó, nó chỉ đơn giản là đình chỉ quá trình đang chờ xử lý SIGCONThoặc SIGKILL.

Giải pháp ở đây cũng là gửi SIGCONTsau của bạn SIGTERMđể quá trình có thể nhận và xử lý tín hiệu.

Thí dụ:

sleep 999 &

# Assume we got PID 456 for this process
kill -TSTP 456    # Suspend the process (nicely)
kill -TERM 456    # Terminate the process (nicely). Nothing happens
kill -CONT 456    # Continue the process so it can exit cleanly

Tài liệu cho Thư viện GNU C giải thích điều này khá tốt, tôi nghĩ (phần nổi bật của tôi):

Trong khi một quá trình bị dừng lại, không có tín hiệu nào có thể được gửi đến nó cho đến khi nó được tiếp tục , ngoại trừ SIGKILLtín hiệu và tín hiệu (rõ ràng) SIGCONT. Các tín hiệu được đánh dấu là đang chờ xử lý, nhưng không được gửi cho đến khi quá trình được tiếp tục. Các SIGKILLtín hiệu luôn luôn gây ra chấm dứt quá trình và không thể bị chặn, xử lý hoặc bỏ qua. Bạn có thể bỏ qua SIGCONT, nhưng nó luôn khiến quá trình được tiếp tục dù thế nào nếu nó bị dừng lại. Gửi SIGCONTtín hiệu đến một quy trình khiến mọi tín hiệu dừng đang chờ xử lý cho quá trình đó bị loại bỏ. Tương tự, mọi SIGCONTtín hiệu đang chờ xử lý cho một quá trình sẽ bị loại bỏ khi nhận được tín hiệu dừng


1
@nohup. câu trả lời mở rộng, nhưng về cơ bản, "có, nó đã xử lý những kill -15gì bạn đã gửi".
roaima

2
@nohup có, theo tài liệu: « Trong khi một quá trình bị dừng, không có tín hiệu nào có thể được gửi đến nó cho đến khi nó được tiếp tục ... Các tín hiệu được đánh dấu là đang chờ xử lý, nhưng không được gửi cho đến khi quá trình được tiếp tục. »
roaima

1
Xem thêm SIGTTIN và SIGTTOU cũng dừng các quá trình
Stéphane Chazelas

1
@ StéphaneChazelas điểm tốt. Tôi đã thêm đề cập đến những điều này nhưng nếu không thì bỏ qua chúng. Xin vui lòng chỉnh sửa khi bạn thấy phù hợp.
roaima

2
@coteyr. Tôi không đồng ý: SIGKILLngăn không cho ứng dụng dọn dẹp, vì vậy sử dụng SIGTERMtốt hơn trong nhiều trường hợp (hầu hết).
roaima

9

SIGTERMcũng giống như bất kỳ tín hiệu nào khác ở chỗ nó có thể bị bắt bởi một quá trình. Nhận tín hiệu sẽ chỉ làm cho quá trình chuyển sang một quy trình xử lý tín hiệu đặc biệt. Đối với SIGTERMhành động mặc định sẽ là chấm dứt quá trình, nhưng ví dụ, một biên tập viên có thể muốn bắt tín hiệu để nó có thể lưu bản sao nháp của bất kỳ tệp đang mở nào trước khi chết. Nếu quá trình bị dừng, nó không thể chạy trình xử lý tín hiệu, nhưng tín hiệu sẽ vẫn chờ xử lý cho đến khi quá trình tiếp tục. Lưu ý rằng số tín hiệu được gửi thường sẽ không được lưu.

Về lý thuyết, hệ thống có thể biết liệu quy trình có cài đặt bộ xử lý tín hiệu SIGTERMhay không và chấm dứt ngay lập tức nếu không. Nhưng (theo nhận xét của Gilles) POSIX yêu cầu tín hiệu sẽ rung cho đến khi quá trình được tiếp tục thông qua SIGCONT.


4
Xin lỗi, nhận xét trước đây của tôi là sai. Trong khi một quá trình bị dừng lại, không có tín hiệu nào được gửi đến nó ngoại trừ SIGKILL và SIGCONT. Ngay cả khi tín hiệu có hành động mặc định là giết quá trình, điều này sẽ bị trì hoãn cho đến khi quá trình được nối lại bởi SIGCONT. POSIX bắt buộc hành vi này.
Gilles 'SO- đừng trở nên xấu xa'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.