我有一个 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 中使用机器级调试器, 如果这些是线程和临界区,则可以查看临界区 并查看哪个线程仍在持有它。我不知道这是否可能 在您选择的平台上使用进程和信号量完成。
您有权访问哪些调试器取决于您运行的平台。
总结:
“你不能从这里到达那里,你必须先去别的地方。”
您需要仔细查看您的代码并弄清楚如何 使用其他方式回答您需要回答的问题。
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 :