Các tệp .pid có đáng tin cậy để xác định xem một quy trình có đang chạy không?


11

Nhiều chương trình như sshd tạo tệp .pid trong / var / run / có chứa ID tiến trình của chúng. Các tệp này có đáng tin cậy để xác định xem một quy trình có đang chạy không? Tôi đoán là các tệp này được tạo bằng tay bởi một quy trình, và do đó sẽ vẫn còn trong hệ thống tệp nếu chương trình gặp sự cố.

Câu trả lời:


16

nói một cách đơn giản, không : một quá trình (ví dụ: daemon) có thể bị sập và không có thời gian để xóa tệp .pid của nó.

Một kỹ thuật để chắc chắn hơn về trạng thái của chương trình: sử dụng kênh truyền thông rõ ràng như ổ cắm. Viết cổng socket trong một tập tin và có supervisorquá trình tra cứu nó.

Bạn cũng có thể sử dụng các dịch vụ của DBus trên Linux: đăng ký một tên cụ thể và yêu cầu quá trình giám sát của bạn (bất cứ điều gì bạn gọi nó) kiểm tra tên đó.

Có rất nhiều kỹ thuật.

Một điều cần nhớ: trách nhiệm của HĐH là quản lý các tệp PID.


1
Tuy nhiên, sự tồn tại của tệp pid, COMBINED với sự tồn tại của quá trình, là đủ. Nếu quá trình thoát, bạn có thể kiểm tra xem. PID được sử dụng lại, nhưng không thường xuyên.
MarkR

2
tần suất một pid được sử dụng lại tùy thuộc vào hệ thống cụ thể được đề cập. Tôi đã thấy một hệ thống được điều khiển bằng chu kỳ ít nhất mỗi ngày. Bạn phải kiểm tra pid, rằng có một quy trình và quy trình đó dường như là quy trình mà bạn mong đợi để sở hữu pid.

@atk: chính xác. Không có một tiêu chuẩn nào và ngay cả khi có một, nó rất có thể không được tôn trọng bởi một số triển khai. Ví dụ: tôi có thể tạo một daemon hoàn toàn không viết tệp PID và sử dụng kênh quay lại để nhận các lệnh quản lý của nó.
jldupont

@atk: thật không may, không có cách nào để đảm bảo rằng PID không được sử dụng lại giữa thời gian kiểm tra và thời gian sử dụng ...
SamB

3

Jldupont đã đúng khi tuyên bố rằng các tệp .pid không đáng tin cậy để xác định xem một quy trình có đang chạy hay không vì tệp có thể không bị xóa trong trường hợp xảy ra sự cố.

Điều kiện cuộc đua sang một bên, tôi thường sử dụng pgrep khi tôi cần biết nếu một quá trình đang chạy. Sau đó tôi có thể tham chiếu chéo đầu ra so với (các) tệp .pid nếu tôi cảm thấy cần thiết.


3

Một tệp chứa id quá trình không đáng tin cậy để xác định xem một quy trình có đang chạy hay không. Nó chỉ là một nguồn đáng tin cậy, để tìm ra id quy trình đã cho cuối cùng cho quy trình.

Khi bạn có id tiến trình, bạn phải kiểm tra thêm, nếu quá trình thực sự đang chạy.

Đây là một ví dụ:

#!/usr/bin/env sh

file="/var/run/sshd.pid"
processid=$(cat /var/run/sshd.pid)

if [ ! -f ${file} ]; then
    echo "File does not exists: ${file}"
    exit 1
fi

if [ ! -r ${file} ]; then
    echo "Insufficient file persmissons: ${file}"
    exit 1
fi

psoutput=$(ps -p ${processid} -o comm=)

if [ $? == 0 ];then
    if [ ${psoutput} == "sshd" ]; then
        echo "sshd process is realy running with process id ${processid}"
        exit 0
    else
        echo "given process id ${processid} is not sshd: ${psoutput}"
        exit 1
    fi
else
    echo "there is no process runing with process id ${processid}"
    exit 0
fi

pgrep là một lệnh hay, nhưng bạn sẽ gặp rắc rối, khi bạn có nhiều phiên bản đang chạy. Ví dụ: khi bạn có một sshd thông thường chạy trên cổng TCP / 22 và bạn có một sshd khác đang chạy trên cổng TCP / 2222, thì pgrep sẽ cung cấp hai id tiến trình khi tìm kiếm sshd ... khi sshd bình thường có pid trong / var /run/sshd.pid và cái khác có thể có pid của nó trong /var/run/sshd-other.pid, bạn có thể phân biệt rõ ràng các quy trình.

Tôi không khuyên bạn chỉ sử dụng ps , đường ống qua một hoặc nhiều đường ống có grepgrep -v cố gắng lọc tất cả những thứ khác mà bạn không quan tâm ... nó hơi giống như sử dụng

find . | grep myfile

để tìm ra, nếu một tập tin thoát.


2

Không đáng tin cậy khi chỉ cần kiểm tra sự tồn tại của một quá trình có cùng pid như trong tệp.

Nhưng nhiều triển khai pidfile cũng thực hiện khóa trên pidfile, do đó nếu quá trình chết, khóa sẽ biến mất. Với điều kiện cơ chế khóa là đáng tin cậy, kiểm tra xem liệu tệp có bị khóa hay không là một cơ chế tương đối đáng tin cậy để xác định xem quy trình ban đầu có còn chạy hay không.


1

Jldupont là chính xác.

Tuy nhiên, bạn có thể gửi tín hiệu quy trình 0 (kill -s 0 pid) để xem liệu quy trình có còn tồn tại không (giả sử bạn có quyền gửi tín hiệu đó - nói chung, chỉ chủ sở hữu của quy trình mới có thể gửi đó là một tín hiệu).


4
Nhưng việc kiểm tra sự tồn tại của một quá trình với PID đó không có nghĩa đó là PID mà bạn quan tâm.
janm

0

Tôi đồng ý với jschmier.

Trên một số hệ thống, bạn không có quyền truy cập vào pgrep. Trong trường hợp như vậy, bạn có thể làm ps -aef | grep <pid>để tìm hiểu xem quá trình có thực sự chạy hay không.


1
Điểm mấu chốt trong câu hỏi là "đáng tin cậy". Làm một ps và tìm kiếm một PID là không đáng tin cậy.
janm

tốt ... giả sử rằng bạn biết tên của chương trình, tại sao bạn nghĩ ps -aef | grep là không đáng tin cậy?
dùng29584

3
Điều kiện cuộc đua: trạng thái của hệ thống đã thay đổi khi thời gian ps kết thúc. Tiêu đề quy trình: một quy trình khác có thể có tiêu đề tương tự với tiêu đề bạn quan tâm. Nhiều trường hợp: Xem xét một hệ thống có hai phiên bản của cùng một dịch vụ, mỗi phiên bản có một tệp PID. Một lần thất bại, và lần khác khởi động lại và nhận được PID của dịch vụ đầu tiên. Làm thế nào để bạn nói? V.v. Không đáng tin cậy, không thể có được vì điều kiện chủng tộc, và có những kỹ thuật đáng tin cậy chỉ hoạt động. Để biết một sự thay thế đáng tin cậy, ví dụ, cr.yp.to/daemontools.html
janm
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.