python - 无法使用调试暂停 python 进程

我有一个 python 脚本,它使用这些行启动多个子进程:

for elm in elements:
    t = multiprocessing.Process(target=sub_process,args=[elm])
    threads.append(t)
    t.start()

for t in threads:
   t.join()

有时,由于某种原因线程停止,脚本永远不会完成。 我正在尝试使用 VSCode 调试器来查找问题并检查它卡在线程本身的位置,但是我在暂停这些子进程时遇到了问题,因为当我在调试器窗口中单击暂停时:

它会暂停主线程和其他一些正常运行的线程,但不会暂停卡住的子进程。 即使当我尝试使用“调用堆栈”窗口一个一个地手动暂停线程时,我仍然只能暂停工作线程而不是卡住的线程。

请帮我解决这个问题,这是一件很难的事情,因为导致进程卡住的事情并不总是发生,因此很难调试。

最佳答案

首先,那些是子进程,而不是线程。理解很重要 差异,尽管它没有回答您的问题。

其次,Python 调试器中的暂停(手动中断)将中断 Python 代码。 它不会在下面执行 Python 的机器代码或机器中中断 下面的代码执行 Python 代码要求的操作系统服务。

如果执行暂停,暂停会出现在上面的Python代码中 当(如果)机器代码返回到 Python 解释器循环时的机器代码。

给出一个完整的例子:

import multiprocessing
import time

elements = ["one", "two", "three"]

def sub_process(gs, elm):
    gs.acquire()
    print("sleep", elm)
    time.sleep(60)
    print("awake", elm);
    gs.release()

def test():
    gs = multiprocessing.Semaphore()

    subprocs = []

    for elm in elements:
        p = multiprocessing.Process(target=sub_process,args=[gs, elm])
        subprocs.append(p)
        p.start()

    for p in subprocs:
        p.join()

if __name__ == '__main__':
    test()

第一个子进程将获取信号量并休眠一分钟, 第二个和第三个子进程将在 gs.acquire() 中等待,直到它们 可以前进。暂停不会打断调试器,直到 subprocess 从 acquire 返回,因为 acquire 在 Python 代码下面。

听起来您知道流程在哪里卡住了, 但你不知道为什么。你需要确定哪些问题 你正在尝试回答。例如:

(假设)其中一个进程卡在 acquire 中。这意味着另一个 进程没有释放信号量。哪个进程是什么代码 获取信号量而不释放它?

查看信号量对象本身可能会告诉您哪个子进程持有它, 但这是一个切线:你能用调试器检查信号量吗 并确定谁持有它?例如,在 Windows 中使用机器级调试器, 如果这些是线程和临界区,则可以查看临界区 并查看哪个线程仍在持有它。我不知道这是否可能 在您选择的平台上使用进程和信号量完成。

您有权访问哪些调试器取决于您运行的平台。

总结:

  • 你不能在机器代码中破坏 Python 调试器
  • 您可以在机器代码调试器中运行 Python 解释器,但是这 根本不会向您展示 Python 代码,这让生活变得有趣。 如果您知道要查找的内容,这可能会有所帮助 - 例如,您可能知道自己在等待信号量时卡住了。
  • 运行机器代码调试器会在你运行时变得更加困难 子流程,因为您需要知道您对哪个子流程感兴趣 在,并附加到那个。如果您使用单个,这会变得更简单 进程和多个线程,因为只有一个进程需要处理。

“你不能从这里到达那里,你必须先去别的地方。”

您需要仔细查看您的代码并弄清楚如何 使用其他方式回答您需要回答的问题。

https://stackoverflow.com/questions/75161513/

相关文章:

c++ - std::variant 使用整数数组中的元素作为 std::variant 中的目标类

fortran - Fortran 能否在逻辑运算中强制遵守参数顺序?

python - 根据条件将新数据从另一个 Dataframe 添加到 Dataframe

c++ - 是不是 vector.at(vector.size()-1) 比 vector.back

python - Pandas 将 df.count() 结果的最后 n 行求和为一行

.net - .NET : System. InvalidOperationException :

python - 查找给定范围内的数字,使给定列表中任何元素的数字的 gcd 始终为 1

c - 尝试复制有关可变参数的 printf 行为

perl - Perl 包变量什么时候超出范围?

vbscript - 当我的 InstallShield 安装程序尝试运行我的 VBS 自定义操作时