ExASIC
分享让工作更轻松

subprocess在IC验证中的应用

subprocess.Popen相比于os.system()多了很多可控制的参数,用起来更灵活。这里记录两段代码,一段是超时退出仿真,另一段代码是检测到Ctrl-C后自动结束所有的仿真进程。

1. 仿真超时

遇到的坑:在shell=True时,p.kill()、p.terminate()会失效。看起来只是把shell进程给结束掉了,shell的子进程ncsim却还在。

经过大神的帮助和查阅stackoverflow相关帖子后,找到下面一个可行的方案。简单来说就是用process group,把所有进程、子进程全总绑定到session_id。

使用时需要注意以下几点:

  1. shell=True
  2. preexec_fn=os.setsid
  3. os.killpg(os.getpgid(p.pid), signal.SIGTERM)

代码如下:

def _run(cmd, stdout=None, timeout=600):
    ret = "timeout"

    p = subprocess.Popen(cmd,
                         stdout=stdout,
                         shell=True,
                         preexec_fn=os.setsid) #new session id

    try:
        t_start = time.time()
        while True:
            time.sleep(5)

            if p.poll() is None: #timeout exit
                dt = time.time() - t_start
                if dt > timeout:
                    #kill all processes attched to this session id
                    os.killpg(os.getpgid(p.pid), signal.SIGTERM) 
                    ret = "timeout"
                    return ret

            else: #normal exit
                ret = "done"
                return ret

2. 检测Ctrl-C自动Kill所有子进程

其实方法就是上面的process group。在except KeyboardInterrupt里发送signal.SIGTERM就可以了。

except KeyboardInterrupt as e:
        print(e)
        os.killpg(os.getpgid(p.pid), signal.SIGTERM)
        ret = "ctrl_c"

这个方法也适用于结束multiprocessing.pool启动的子进程。

multiprocessing相关的内容可以参考这里:multiprocessing在并行仿真中的应用

阅读数:
更多文章:文章目录
解惑专区
(支持markdown插入源代码)
欢迎使用ExASIC订阅服务
仅用于ExASIC最新文章通知,方便及时阅读。
友情链接: IC技术圈问答ReCclayCrazyFPGA