Tôi đang cố gắng xây dựng một trình tiện ích Python để khởi chạy các quy trình độc lập hoàn toàn khác.Không xác định quá trình tạo daemon được sinh ra trong Python
Ý tưởng chung là dành cho lệnh trình bao đã cho, thăm dò sau mỗi vài giây và đảm bảo rằng chính xác k phiên bản lệnh đang chạy. Chúng tôi giữ một thư mục pidfiles và khi chúng tôi thăm dò ý kiến, chúng tôi xóa các pidfile mà các pidfile không còn chạy nữa và khởi động (và tạo các pidfiles), tuy nhiên, chúng tôi cần có nhiều quy trình để truy cập k trong số chúng.
Quy trình con cũng cần phải hoàn toàn độc lập, để nếu quá trình cha mẹ chết thì trẻ sẽ không bị giết. Từ những gì tôi đã đọc, có vẻ như không có cách nào để làm điều này với mô-đun subprocess
. Để kết thúc này, tôi đã sử dụng đoạn đề cập ở đây:
http://code.activestate.com/recipes/66012-fork-a-daemon-process-on-unix/
tôi đã thực hiện một vài điều chỉnh cần thiết (bạn sẽ nhìn thấy những dòng chú thích trong đoạn mã đính kèm):
- Phụ huynh gốc quá trình không thể thoát vì chúng tôi cần trình khởi chạy để tiếp tục vô thời hạn.
- Quy trình con cần bắt đầu bằng cùng một ngày với cha mẹ.
Dưới đây là fn spawn của tôi và một bài kiểm tra:
import os
import sys
import subprocess
import time
def spawn(cmd, child_cwd):
"""
do the UNIX double-fork magic, see Stevens' "Advanced
Programming in the UNIX Environment" for details (ISBN 0201563177)
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
"""
try:
pid = os.fork()
if pid > 0:
# exit first parent
#sys.exit(0) # parent daemon needs to stay alive to launch more in the future
return
except OSError, e:
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)
# decouple from parent environment
#os.chdir("/") # we want the children processes to
os.setsid()
os.umask(0)
# do second fork
try:
pid = os.fork()
if pid > 0:
# exit from second parent
sys.exit(0)
except OSError, e:
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)
# redirect standard file descriptors
sys.stdout.flush()
sys.stderr.flush()
si = file('/dev/null', 'r')
so = file('/dev/null', 'a+')
se = file('/dev/null', 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
pid = subprocess.Popen(cmd, cwd=child_cwd, shell=True).pid
# write pidfile
with open('pids/%s.pid' % pid, 'w') as f: f.write(str(pid))
sys.exit(1)
def mkdir_if_none(path):
if not os.access(path, os.R_OK):
os.mkdir(path)
if __name__ == '__main__':
try:
cmd = sys.argv[1]
num = int(sys.argv[2])
except:
print 'Usage: %s <cmd> <num procs>' % __file__
sys.exit(1)
mkdir_if_none('pids')
mkdir_if_none('test_cwd')
for i in xrange(num):
print 'spawning %d...'%i
spawn(cmd, 'test_cwd')
time.sleep(0.01) # give the system some breathing room
Trong tình huống này, mọi thứ dường như làm việc tốt, và các quá trình con tồn tại ngay cả khi cha mẹ bị giết. Tuy nhiên, tôi vẫn đang chạy vào một giới hạn đẻ trứng trên cha mẹ ban đầu. Sau ~ 650 spawn (không được kiêm nhiệm, các em đã hoàn thành) quá trình cha mẹ nghẹn với lỗi:
spawning 650...
fork #2 failed: 35 (Resource temporarily unavailable)
Có cách nào để viết lại chức năng đẻ trứng của tôi để tôi có thể đẻ trứng các quá trình con độc lập vô thời hạn? Cảm ơn!
Bảng xử lý của bạn trông như thế nào? Liệu ps ps' có cho thấy một đống các quá trình zombie khổng lồ đang chờ được gặt hái? (Tôi không thấy bất kỳ mã nào ở đây để 'wait()' trên các con đầu tiên được phân chia.) – sarnold
Tôi nghĩ vậy: http://pastebin.com/qDrFmHWk –
Hãy xem xét pyinotify để theo dõi những thay đổi trong thư mục thay thế bỏ phiếu. – aitchnyu