BugKiller: Python subprocess超时后,无法kill进程的问题

您所在的位置:网站首页 Python3进程kill不掉 BugKiller: Python subprocess超时后,无法kill进程的问题

BugKiller: Python subprocess超时后,无法kill进程的问题

2024-04-20 08:46| 来源: 网络整理| 查看: 265

出现问题的代码是酱汁的:

process = subprocess.Popen("phantomjs crawler.js {url} {method} {data}", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) try: (output, error) = process.communicate(timeout=TIMEOUT) re_result = re.findall(r"~~~~123(.*?)321~~~~", output.decode(), re.I|re.S) if len(re_result) == 0: print_error("Can't find result, %s" % cmd) return [] res = simplejson.loads(re_result[0]) for item in res: item["url"] = Parser.get_url(url, item["url"]) return res except subprocess.TimeoutExpired: process.kill() print_error("TIMEOUT: %s" % cmd) except Exception as e: print(e)

由于PhantomJS的问题,导致任务超时。超时关闭是在Python中处理的,调用了process.kill(),但在实际测试中发现PhantomJS进程并没有被kill掉。

为了Debug,我在process.kill()之前,插入了一句print(process.pid)。原本以为是kill()函数没有正常运行,但让人惊讶的是,根据打印出来的pid,进程中并没有subprocess进程残留,打印的pid和未结束的PhantomJS进程pid并不相同,且phantomjs.pid = process.pid + 1。看起来是subprocess在调度任务的时候,开启了两个进程,在父进程被kill的时候,并没有kill子进程(或者两个进程之间根本没有父子关系)。

很快查到了问题所在,shell=True 参数会模拟在shell中执行,先是起了shell进程,再从shell起了phantomjs进程。解决方案( 去掉了shell=True,改用list格式传参。):

process = subprocess.Popen(["phantomjs", "crawler.js", {url}, {method}, {data}], stdout=subprocess.PIPE, stderr=subprocess.PIPE)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3