Quá trình con cháu


20

Tôi đang cố gắng xây dựng một container quy trình. Container sẽ kích hoạt các chương trình khác. Ví dụ: tập lệnh bash khởi chạy các tác vụ chạy nền với cách sử dụng '&'.

Tính năng quan trọng mà tôi theo đuổi là đây: khi tôi giết container, mọi thứ được sinh ra dưới nó sẽ bị giết. Không chỉ con cái trực tiếp, mà con cháu của họ cũng vậy.

Khi tôi bắt đầu dự án này, tôi đã lầm tưởng rằng khi bạn giết một quá trình, những đứa trẻ của nó cũng tự động bị giết. Tôi đã tìm kiếm lời khuyên từ những người có cùng ý tưởng không chính xác. Mặc dù có thể bắt được tín hiệu và truyền lại sự giết chóc cho trẻ em, nhưng đó không phải là điều tôi đang tìm kiếm ở đây.

Tôi tin rằng những gì tôi muốn có thể đạt được, bởi vì khi bạn đóng một xterm, bất cứ thứ gì đang chạy trong nó đều bị giết trừ khi nó không còn nữa. Điều này bao gồm các quá trình mồ côi. Đó là những gì tôi đang tìm cách tái tạo.

Tôi có một ý tưởng rằng những gì tôi đang nới lỏng liên quan đến các phiên unix.

Nếu có một cách đáng tin cậy để xác định tất cả con cháu của một quá trình, thì cũng có thể hữu ích để gửi cho chúng các tín hiệu tùy ý. ví dụ SIGUSR1.


Chà, giết quá trình cha mẹ gửi SIGHUPcho nó quá trình con cái trực tiếp. Trình xử lý mặc định của tín hiệu gác máy hủy bỏ quá trình thực thi quy trình, vì vậy tuyến đường mặc định là tiêu diệt tất cả các hậu duệ. Đọc thêm về các quy trình và nhóm quy trình.
alex

Đóng xterm sẽ giết chết mọi thứ sinh ra trong xterm vì TTY bị phá hủy. Nếu bạn có thể đưa ra một cách để tạo ra một tty mà các tiến trình con có thể sử dụng, thì bạn có thể phá hủy TTY và hoàn thành điều tương tự. Bất kỳ quy trình nào không đóng TTY (nohup & friends) sẽ nhận được SIGHUP.
Patrick

Câu trả lời:


23

Nếu bạn gửi tín hiệu đến một quy trình, quy trình đó sẽ bị hủy. Tôi tự hỏi làm thế nào tin đồn rằng giết một quá trình cũng giết chết các quá trình khác đã bắt đầu, nó có vẻ đặc biệt phản trực giác.

Tuy nhiên, có nhiều cách để giết nhiều hơn một quá trình. Nhưng bạn sẽ không gửi tín hiệu cho một quá trình. Bạn có thể tiêu diệt toàn bộ nhóm quy trình bằng cách gửi tín hiệu đến -1234 trong đó 1234 là PGID (ID nhóm quy trình), đây là PID của người lãnh đạo nhóm quy trình. Khi bạn chạy một đường ống , toàn bộ đường ống bắt đầu như một nhóm quy trình (các ứng dụng có thể thay đổi điều này bằng cách gọi setpgidhoặc setpgrp).

Khi bạn bắt đầu các quy trình trong nền ( foo &), chúng nằm trong nhóm quy trình riêng của chúng. Các nhóm quy trình được sử dụng để quản lý truy cập vào thiết bị đầu cuối; thông thường chỉ có nhóm quy trình tiền cảnh có quyền truy cập vào thiết bị đầu cuối. Các công việc nền vẫn duy trì trong cùng một phiên , nhưng không có cơ sở nào để giết cả phiên hoặc thậm chí để liệt kê các nhóm quy trình hoặc quy trình trong một phiên, do đó không giúp được gì nhiều.

Khi bạn đóng một thiết bị đầu cuối, hạt nhân sẽ gửi tín hiệu SIGHUPđến tất cả các quy trình có nó như là thiết bị đầu cuối kiểm soát của chúng . Các quy trình này tạo thành một phiên , nhưng không phải tất cả các phiên đều có thiết bị đầu cuối kiểm soát. Do đó, đối với dự án của bạn, một khả năng là bắt đầu tất cả các quy trình trong thiết bị đầu cuối của riêng chúng, được tạo bởi tập lệnh , màn hình , v.v. Giết quá trình giả lập thiết bị đầu cuối để tiêu diệt các quy trình có trong đó (giả sử chúng chưa được bảo mật setsid).

Bạn có thể cung cấp sự cô lập nhiều hơn bằng cách chạy các quy trình với tư cách là người dùng của chính họ, người không làm gì khác. Sau đó, thật dễ dàng để giết tất cả các quy trình: chạy kill( cuộc gọi hệ thống hoặc tiện ích ) với tư cách là người dùng đó và sử dụng -1 làm đối số PID để tiêu diệt, nghĩa là tất cả các quy trình của người dùng đó xử lý.

Bạn có thể cung cấp cách ly thậm chí nhiều hơn, nhưng với thiết lập nhiều hơn đáng kể bằng cách chạy các quy trình được chứa trong một thùng chứa thực tế .


Nếu bạn lập trình các quy trình của riêng mình, thì bạn có thể sử dụng một cái gì đó như : prctl(PR_SET_PDEATHSIG, SIGHUP);, thông tin thêm: man7.org/linux/man-pages/man2/prctl.2.html
Alexis Wilke

Gilles, bạn đề cập đến điều này - "Khi bạn đóng một thiết bị đầu cuối, hạt nhân sẽ gửi tín hiệu SIGHUP đến tất cả các quy trình có nó như là thiết bị đầu cuối kiểm soát của chúng". Từ điều này, tôi đoán rằng thiết bị đầu cuối sẽ gửi SIGHUP cho người lãnh đạo phiên (shell), người chuyển tiếp nó tới tất cả các nhóm quy trình trong phiên. Điều nào trong hai người sẽ đúng?
iruvar

4

Trong kịch bản cha mẹ bẫy tín hiệu giết và có nó giết tất cả trẻ em. Ví dụ,

#!/bin/bash
# kill the parent and children together
trap "kill 0" EXIT
# create all the children
for n in $(seq 1 100)
do
    ( echo "begin $n"; sleep 60; echo "end $n" ) &
done
# wait for the children to complete
wait

2

Một cách đáng tin cậy để xác định tất cả các hậu duệ của một tiến trình là sử dụng lệnh pstree <pid>trong đó pid là id tiến trình cha của bạn.

Đọc trang người đàn ông pstree ở đây .

Để báo hiệu tất cả các thành viên của một nhóm quy trình: killpg(<pgrp>, <sig>);
trong đó pgrp là số nhóm quy trình và sig là tín hiệu.

Để chờ trẻ em trong một nhóm quy trình được chỉ định: waitpid(-<pgrp>, &status, ...);

Một cách khác để làm những gì bạn đang làm là chạy thùng chứa quy trình của bạn trong một vỏ bash mới. Tạo shell bash mới bằng lệnh bashvà sau đó chạy các quy trình của bạn. Khi bạn muốn tất cả các quá trình được kết thúc, thoát khỏi shell bằng lệnh exit.


Tôi nghĩ killpg sẽ cho phép tôi làm những gì tôi cần làm. Cảm ơn.
Craig Turner

1

Sử dụng

unshare -fp --kill-child -- yourprogram

Nếu bạn giết unshare, tất cả các quá trình con ( yourprogramcó thể đã sinh ra) sẽ bị giết.

Điều này bây giờ có thể với produc-linux 2.32; Tôi thực hiện điều này ngược dòng . Nó yêu cầu không gian tên người dùng (tùy chọn cấu hình kernel CONFIG_USER_NS=y) hoặc quyền root. Xem thêm tại đây .


0

Lệnh rkill từ gói pslist gửi tín hiệu đã cho (hoặc SIGTERMtheo mặc định) đến quy trình được chỉ định và tất cả các hậu duệ của nó:

rkill [-SIG] pid/name...

0

Một lựa chọn khác để giết tất cả hậu duệ của vỏ: jobs -p | xargs -n 1 pkill -P

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.