Apakah ada cara untuk memeriksa untuk melihat apakah pid sesuai dengan proses yang valid? Saya mendapatkan pid dari sumber yang berbeda selain dari os.getpid()
dan saya perlu memeriksa untuk melihat apakah proses dengan pid itu tidak ada di mesin.
Saya membutuhkannya untuk tersedia di Unix dan Windows. Saya juga memeriksa untuk melihat apakah PID TIDAK digunakan.
Jawaban:
Mengirim sinyal 0 ke pid akan memunculkan pengecualian OSError jika pid tidak berjalan, dan tidak melakukan apapun.
sumber
os.kill(pid, 0)
sama sepertios.kill(pid, signal.CTRL_C_EVENT)
yang dapat menghentikan proses (atau gagal). Saya mendapatkanOSError
tempaterrno==EINVAL
ketika saya mencoba ini pada sebuah subproses.Lihat
psutil
modulnya:Ini memiliki fungsi yang disebut
pid_exists()
yang dapat Anda gunakan untuk memeriksa apakah proses dengan pid yang diberikan ada.Berikut contohnya:
Sebagai referensi:
sumber
psutil
implementasinyapid_exists()
di POSIX . Bandingkan dengan jawaban @Giampaolo Rodolà (penulispsutil
)kode mluebke tidak 100% benar; kill () juga dapat meningkatkan EPERM (akses ditolak) dalam hal ini berarti ada proses. Ini seharusnya berhasil:
(diedit sesuai komentar Jason R. Coombs)
Anda tidak dapat melakukan ini di Windows kecuali Anda menggunakan pywin32, ctypes atau modul ekstensi C. Jika Anda setuju dengan bergantung dari lib eksternal Anda dapat menggunakan psutil :
sumber
Jawaban yang melibatkan pengiriman 'sinyal 0' ke proses hanya akan berfungsi jika proses tersebut dimiliki oleh pengguna yang menjalankan pengujian . Jika tidak, Anda akan mendapatkan izin
OSError
karena , meskipun pid ada di sistem.Untuk melewati batasan ini, Anda dapat memeriksa apakah
/proc/<pid>
ada:Ini jelas berlaku untuk sistem berbasis linux saja.
sumber
PermissionError
berarti pid ada , Anda mendapatkanProcessLookupError
jika pid tidak ada.OSError
karena izin ditolak dapat dibedakan dari yang lain - baik melalui melihat errno atau melalui menangkap lebih khususPermissionError
/ProcessLookupError
pengecualian yang berasal dariOSError
. Selanjutnya, Anda hanya mendapatkan kesalahan izin jika proses tersebut ada. Jadi, contoh Anda hanyalah metode alternatif yang berfungsi di Linux dan beberapa Unix lainnya tetapi tidak lebih lengkap daripada memanggil dengan benaros.kill(pid, 0)
./proc
procfs hanya keluar di Linux, bahkan di BSD atau OSX.Di Python 3.3+, Anda bisa menggunakan nama pengecualian sebagai ganti konstanta errno. Versi Posix :
sumber
Lihat di sini untuk cara khusus windows untuk mendapatkan daftar lengkap proses yang berjalan dengan ID mereka. Ini akan menjadi seperti itu
Anda kemudian dapat memverifikasi pid yang Anda dapatkan terhadap daftar ini. Saya tidak tahu tentang biaya kinerja, jadi sebaiknya Anda memeriksa ini jika Anda akan sering melakukan verifikasi pid.
Untuk * NIx, cukup gunakan solusi mluebke.
sumber
Membangun di atas ntrrgc, saya telah meningkatkan versi windows sehingga memeriksa kode keluar proses dan memeriksa izin:
sumber
GetExistCodeProcess
membutuhkanPROCESS_QUERY_INFORMATION
danPROCESS_QUERY_LIMITED_INFORMATION
hak akses.GetExitCodeProcess
menerima sebuah pegangan dan sebuah pointer dan dalam contoh ini ia menerima sebuahExitCodeProcess
struktur sebagai parameter kedua yang seharusnya hanya sebuah pointer.Menggabungkan jawaban Giampaolo Rodolà untuk POSIX dan milik saya untuk Windows, saya mendapatkan ini:
sumber
GetExitCodeProcess
dan memastikan bahwa Anda memiliki akses.kernel32.OpenProcess
tidak cukup. Seperti yang ditunjukkan di sini "jika proses keluar baru-baru ini, pid mungkin masih ada untuk pegangan." Jikakernel32.OpenProcess
mengembalikan nilai bukan nol, kita masih perlukernel32.GetExitCodeProcess
lebih jauh untuk memeriksa kode keluar.Di Windows, Anda dapat melakukannya dengan cara ini:
Pertama-tama, dalam kode ini Anda mencoba untuk mendapatkan pegangan untuk proses dengan pid yang diberikan. Jika pegangannya valid, tutup handle untuk proses dan kembalikan True; jika tidak, Anda mengembalikan False. Dokumentasi untuk OpenProcess: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx
sumber
Ini akan berfungsi untuk Linux, misalnya jika Anda ingin memeriksa apakah banshee sedang berjalan ... (banshee adalah pemutar musik)
sumber
os.kill(pid, 0)
atau melihat/proc/{pid}
. Alih-alih mengeksekusi satu syscall, kode Anda mem-fork seorang anak, mengeksekusi shell pada turunan itu, shell menafsirkan skrip-shell mini Anda yang berlebihan, shell mem-fork turunan lain yang menjalankan pgrep dan akhirnya pgrep melakukan iterasi/proc
. Jawaban Anda tidak menjawab pertanyaan yang diposting. OP meminta metode yang diberi PID. Metode Anda membutuhkan nama proses.Saya akan mengatakan gunakan PID untuk tujuan apa pun Anda mendapatkannya dan menangani kesalahan dengan anggun. Jika tidak, ini adalah balapan klasik (PID mungkin valid jika Anda memeriksa validitasnya, tetapi segera hilang nanti)
sumber