• 作者:老汪软件技巧
  • 发表时间:2023-12-28 14:00
  • 浏览量:

appium_port = get_free_appium_port()
cmd = f"appium -p {appium_port} &"
print(cmd)
subprocess.Popen(
   cmd,
   shell=True,
   # 这里修改
   stdout=open(f"./{appium_port}.log", "a+"),
   stderr=subprocess.STDOUT,
)

(父进程)用.Popen新建一个进程(子进程)去开启一个shell, shell新开一个子进程(孙进程)去执行ping 的命令。

由于孙进程ping 一直在执行,就类似于一个程序,一直在运行。

在超时时间后,父进程杀掉了shell子进程,但是父进程阻塞在了函数了,是阻塞在了调用wait()函数之前,感兴趣的朋友可以看一下源码函数,linux系统重点看ll和lect函数,你会发现是阻塞在了while循环里面,因为父进程一直在获取输出,而孙进程一直像一个程序一样,一直在往子进程的输出写东西,而子进程的文件句柄继承自父进程。

虽然shell子进程被杀掉了,但是父进程里面的逻辑并没有因为子进程被意外的干掉而终止,(因为孙进程一直有输出到子进程的,导致子进程的一直有输出,也就是父进程的也有输出),所以while循环一直成立,就导致了阻塞,进而导致wait()没有被调用,所以子进程没有被回收,就成了僵尸进程。

要完美的解决这个问题就是即要能获取到.Popen的进程的输出,在超时又要能杀掉子进程,让主进程不被阻塞。