python 子进程.check_output:threading.lock.acquire(block,timeout)如果设置了超时则永远不会返回

mdfafbf1  于 2023-02-18  发布在  Python
关注(0)|答案(1)|浏览(158)

我有一个需要退出的锁进程,所以我设置了一个超时,但是它仍然永远挂起。这是windows10和python3.10.2,shell=True|假不执行任何操作
我在30秒后执行键盘中断:

Traceback (most recent call last):
  File "C:\dist\work\rancher\bin\ranchercli.py", line 87, in <module>
    dat = tools.exe.psexe(f"{ranchercli},context,switch".split(','), returnjson=False, shell=shell, timer=3)
  File "c:\dist\work\rancher\tools\exe.py", line 51, in psexe
    out = subprocess.check_output(shell_exe, shell=shell, timeout=timer)
  File "C:\dist\Python310\lib\subprocess.py", line 420, in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
  File "C:\dist\Python310\lib\subprocess.py", line 512, in run
    exc.stdout, exc.stderr = process.communicate()
  File "C:\dist\Python310\lib\subprocess.py", line 1149, in communicate
    stdout, stderr = self._communicate(input, endtime, timeout)
  File "C:\dist\Python310\lib\subprocess.py", line 1523, in _communicate
    self.stdout_thread.join(self._remaining_time(endtime))
  File "C:\dist\Python310\lib\threading.py", line 1089, in join
    self._wait_for_tstate_lock()
  File "C:\dist\Python310\lib\threading.py", line 1109, in _wait_for_tstate_lock
    if lock.acquire(block, timeout):
KeyboardInterrupt

从python310\lib\threading.py这个函数从来没有返回过,可能是阻塞了什么。真的很感激一些关于如何调试这个的提示。我如何检查线程状态?

def _wait_for_tstate_lock(self, block=True, timeout=-1):
        # Issue #18808: wait for the thread state to be gone.
        # At the end of the thread's life, after all knowledge of the thread
        # is removed from C data structures, C code releases our _tstate_lock.
        # This method passes its arguments to _tstate_lock.acquire().
        # If the lock is acquired, the C code is done, and self._stop() is
        # called.  That sets ._is_stopped to True, and ._tstate_lock to None.
        lock = self._tstate_lock
        if lock is None:
            # already determined that the C code is done
            assert self._is_stopped
            return

        try:
            if lock.acquire(block, timeout):
                lock.release()
                self._stop()
        except:
            if lock.locked():
                # bpo-45274: lock.acquire() acquired the lock, but the function
                # was interrupted with an exception before reaching the
                # lock.release(). It can happen if a signal handler raises an
                # exception, like CTRL+C which raises KeyboardInterrupt.
                lock.release()
                self._stop()
            raise
4bbkushb

4bbkushb1#

请注意,在此行中没有转发超时:

File "C:\dist\Python310\lib\subprocess.py", line 512, in run
    exc.stdout, exc.stderr = process.communicate()

这是一个尚未在Windows上修复的错误:

解决方法是强制默认超时:

from functools import partial

subprocess.Popen.communicate = partial(subprocess.Popen.communicate, timeout=30)

相关问题