我有开始使用一个子Python程序(准确地说,Django应用程序) subprocess.Popen
。 由于我的应用程序的体系结构的限制,我不能使用Popen.terminate()
终止子和Popen.poll()
来检查时,进程已经终止。 这是因为我不能抱着一个变量的启动子的参考。
相反,我要的进程id写pid
到文件pidfile
子进程启动时。 当我想阻止子,我打开这个pidfile
并使用os.kill(pid, signal.SIGTERM)
停止它。
我的问题是:我如何才能找到当子真的结束? 使用signal.SIGTERM
它需要大约1-2分钟,最后终止调用后os.kill()
首先,我认为os.waitpid()
将成为这个任务的正确的事情,但是当我后把它os.kill()
它给了我OSError: [Errno 10] No child processes
。
顺便说一句,我开始并使用两种形式从HTML模板停止子和程序逻辑是一个Django视图中。 当我的应用程序是在调试模式下的异常被显示在我的浏览器。 这可能也很重要,要知道,我在我的观点(也称子python manage.py crawlwebpages
)本身调用另一个子流程,即Scrapy履带的一个实例。 我写的pid
此Scrapy实例到的pidfile
,这是我要终止的。
下面是相关的代码:
def process_main_page_forms(request):
if request.method == 'POST':
if request.POST['form-type'] == u'webpage-crawler-form':
template_context = _crawl_webpage(request)
elif request.POST['form-type'] == u'stop-crawler-form':
template_context = _stop_crawler(request)
else:
template_context = {
'webpage_crawler_form': WebPageCrawlerForm(),
'stop_crawler_form': StopCrawlerForm()}
return render(request, 'main.html', template_context)
def _crawl_webpage(request):
webpage_crawler_form = WebPageCrawlerForm(request.POST)
if webpage_crawler_form.is_valid():
url_to_crawl = webpage_crawler_form.cleaned_data['url_to_crawl']
maximum_pages_to_crawl = webpage_crawler_form.cleaned_data['maximum_pages_to_crawl']
program = 'python manage.py crawlwebpages' + ' -n ' + str(maximum_pages_to_crawl) + ' ' + url_to_crawl
p = subprocess.Popen(program.split())
template_context = {
'webpage_crawler_form': webpage_crawler_form,
'stop_crawler_form': StopCrawlerForm()}
return template_context
def _stop_crawler(request):
stop_crawler_form = StopCrawlerForm(request.POST)
if stop_crawler_form.is_valid():
with open('scrapy_crawler_process.pid', 'rb') as pidfile:
process_id = int(pidfile.read().strip())
print 'PROCESS ID:', process_id
os.kill(process_id, signal.SIGTERM)
os.waitpid(process_id, os.WNOHANG) # This gives me the OSError
print 'Crawler process terminated!'
template_context = {
'webpage_crawler_form': WebPageCrawlerForm(),
'stop_crawler_form': stop_crawler_form}
return template_context
我能做什么? 非常感谢你!
编辑:
据伟大的答案给出亚切克Konieczny ,我可以通过改变功能我的代码解决我的问题_stop_crawler(request)
于以下内容:
def _stop_crawler(request):
stop_crawler_form = StopCrawlerForm(request.POST)
if stop_crawler_form.is_valid():
with open('scrapy_crawler_process.pid', 'rb') as pidfile:
process_id = int(pidfile.read().strip())
# These are the essential lines
os.kill(process_id, signal.SIGTERM)
while True:
try:
time.sleep(10)
os.kill(process_id, 0)
except OSError:
break
print 'Crawler process terminated!'
template_context = {
'webpage_crawler_form': WebPageCrawlerForm(),
'stop_crawler_form': stop_crawler_form}
return template_context