如果删除“signal.signal”函数调用会发生什么

问题描述 投票:0回答:1

我有这个遗留代码,我想为其添加错误处理。令我惊讶的是,我发现其中的 try 和 except 不起作用。经过一番调试后,发现这是因为

signal.signal(signal.SIGCHLD, signal.SIG_IGN)
代码使主进程忽略了子异常。所以在原来的代码中,永远不会到达
except subprocess.CalledProcessError as e:
。我怀疑以前的程序员是否正确完成了此操作,并且我想删除
signal.signal(signal.SIGCHLD, signal.SIG_IGN)
行,以便
try...except
能够按预期工作。但我不知道这是否会在处理子进程时造成任何麻烦。(例如,我不知道创建的僵尸子进程)。有什么修改建议吗?

import threading
import logging
import queue
import subprocess
import signal


class Worker(threading.Thread):
    def __init__(self, thread_id, work_queue):
        threading.Thread.__init__(self)
        self._thread_id = thread_id
        self._queue = work_queue

    def run(self):
        while not self._queue.empty():
            module = self._queue.get()
            try:
                subprocess.run(["python3.8", module], check=True)
            except subprocess.CalledProcessError as e:
                logging.error(
                    "Worker: {} failed to process '{}'. Error: {}".format(
                        self._thread_id,
                        module.split("/")[-1], e))
            self._queue.task_done()
        logging.info("Worker: {} has exited!".format(self._thread_id))


def process_modules(modules):
    modulesQueue = queue.Queue()
    for i in modules:
        modulesQueue.put(i)

    workers = []
    for i in range(1):
        worker = Worker(i,
                        modulesQueue)  # create a worker for each available GPU
        workers.append(worker)
        worker.start()  # start the worker
    modulesQueue.join()  # wait for all modules to be processed


def validate_models():
    modules = ["case1", "case2"]
    process_modules(modules)
    return modules


if __name__ == "__main__":
    # Ignore SIGCHLD handler to not creating zombie child processes.
    signal.signal(signal.SIGCHLD, signal.SIG_IGN)

    validate_models()
python multithreading signals multiprocess sigchld
1个回答
0
投票

这里不需要任何信号处理。也不需要排队。实在是太复杂了。下面是一些代码,只需几行即可实现相同的功能:

from concurrent.futures import ThreadPoolExecutor
import logging
import subprocess

PYTHON = "/Library/Frameworks/Python.framework/Versions/3.12/bin/python3"

def process(module):
    try:
        subprocess.run([PYTHON, module], check=True)
    except subprocess.CalledProcessError as e:
        logging.error(f"Module {module} failed due to {e}")

def main():
    modules = ["module1.py", "module2.py"]
    with ThreadPoolExecutor() as exe:
        exe.map(process, modules)


if __name__ == "__main__":
    main()

这里唯一的潜在问题是被调用的“模块”是否被卡住。您必须编写一些相当复杂的代码来管理这种可能性

© www.soinside.com 2019 - 2024. All rights reserved.