में अनिश्चितकालीन डिमोनाइज्ड प्रक्रिया उत्पन्न हो रही है, मैं एक पाइथन डिमन बनाने की कोशिश कर रहा हूं जो अन्य पूरी तरह से स्वतंत्र प्रक्रियाओं को लॉन्च करता है।पाइथन
सामान्य विचार किसी दिए गए खोल कमांड के लिए है, हर कुछ सेकंड में मतदान करें और सुनिश्चित करें कि के कमांड के उदाहरण चल रहे हैं। हम पिडफाइल की निर्देशिका रखते हैं, और जब हम मतदान करते हैं तो हम उन पिडफाइल को हटाते हैं जिनके पिड अब नहीं चल रहे हैं और शुरू होते हैं (और इसके लिए पिडफाइल बनाते हैं) हालांकि कई प्रक्रियाओं को हमें के तक पहुंचने की आवश्यकता है।
बच्चे की प्रक्रियाओं को पूरी तरह से स्वतंत्र होने की भी आवश्यकता है, ताकि यदि माता-पिता की प्रक्रिया मर जाती है तो बच्चों को मार नहीं दिया जाएगा। मैंने जो पढ़ा है, उससे ऐसा लगता है कि subprocess
मॉड्यूल के साथ ऐसा करने का कोई तरीका नहीं है। इस उद्देश्य से, मैं टुकड़ा यहाँ उल्लेख प्रयोग किया है:
http://code.activestate.com/recipes/66012-fork-a-daemon-process-on-unix/
मैं एक जोड़े को आवश्यक संशोधन किए गए हैं (आप लाइनों संलग्न स्निपेट में बाहर टिप्पणी की देखेंगे):
- मूल माता पिता प्रक्रिया बाहर नहीं निकल सकती है क्योंकि हमें अनिश्चित काल तक जारी रखने के लिए लॉन्चर डिमन की आवश्यकता है।
- बच्चे प्रक्रियाओं को माता-पिता के समान सीडब्ल्यूडी से शुरू करने की आवश्यकता है।
यहाँ मेरी अंडे fn और एक परीक्षण है:
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
इस स्थिति में, सब कुछ ठीक काम करने के लिए लगता है, और जब माता-पिता की मौत हो गई है बच्चे प्रक्रियाओं भी लागू हैं। हालांकि, मैं अभी भी मूल अभिभावक पर एक स्पॉन सीमा में चल रहा हूं। बाद ~ 650 spawns (नहीं समवर्ती, बच्चों समाप्त कर दिया है) माता पिता प्रक्रिया त्रुटि के साथ chokes:
spawning 650...
fork #2 failed: 35 (Resource temporarily unavailable)
मेरे अंडे समारोह के पुनर्लेखन के लिए इतना है कि मैं इन स्वतंत्र बच्चे प्रक्रियाओं को अनिश्चित काल के अंडे कर सकते हैं कोई तरीका है? धन्यवाद!
आपकी प्रक्रिया तालिका कैसी दिखती है? क्या 'ps aux' ज़ोंबी प्रक्रियाओं का एक विशाल ढेर दिखाता है जो काटने की प्रतीक्षा कर रहा है? (मुझे पहले-फोर्क वाले बच्चों पर 'प्रतीक्षा()' में कोई कोड नहीं दिख रहा है।) – sarnold
मुझे ऐसा लगता है: http://pastebin.com/qDrFmHWk –
इसके बजाय निर्देशिका में परिवर्तनों की निगरानी करने के लिए pyinotify पर विचार करें मतदान के 'पीआईडी = subprocess.Popen (cmd, CWD = child_cwd, खोल = सच, close_fds = सच) लेकिन यह अभी भी विफल रहा है .pid': ' 647 को उत्पन्न करने ... कांटा # 2 में विफल रहा है – aitchnyu