Unable to handle signal in multiprocessing.Process target

Asked 2 years ago, Updated 2 years ago, 104 views

In multiprocessing.Process, I want to handle SIGTERM in the target function (which is passed as the argument target), but it doesn't work
What should I do?

If you press the Start button in a program using the GUI, the test_main function will run in another process.
When you press the Stop button, the SIGTERM is sent to the process that started when you press the Start button.
However, within test_main, the Webdriver is running, and I would like to finish the process after clearing this Webdriver (driver.quit().

Therefore, I would like to set signal.signal in test_main and finish the process after cleaning up the webdriver when I receive the SIGTERM, but even if I press the Stop button and send the SIGTERM, it won't work.


import tkinter as tk
from multiprocessing import Process
from tkinter import messagebox
import sys
import signal
import time
importos
from selenium.webdriver.support.wait import WebDriverWait
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support import expected_conditions as EC


def create_driver():
    options=Options()
    if sys.platform=="darwin":
        options.binary_location='/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary'
    # options.add_experimental_option("detach", True)
    if sys.platform=="win32":
        options.binary_location="C:\\(user_home)\\AppData\\Local\\Google\\Chrome SxS\\Application\\chrome.exe"# location of chrome canary for windows
    options.add_argument('--headless')
    # options.add_argument('--disable-gpu')
    options.add_argument('--reduce-security-for-testing')
    options.add_argument('--allow-insecure-localhost')
    if sys.platform=="win32":
        chromedriver_path=r ".\chromedriver"
    else:
        chromedriver_path="./chromedriver"

    driver=webdriver.Chrome(chromedriver_path, chrome_options=options)
    return driver



class GUI(tk.Frame):
    def__init__(self, master=None):
        super().__init__(master)
        self.cur_process=None
        self.pack()
        self.create_widget()

    def create_widget(self):
        self.start=tk.Button(self, width=5, padx=10, pady=3)
        self.start ["text"] = "Start"
        self.start ["command"] = self.start_event
        self.start.grid (row=2, column=2, columnspan=2, padx=4, pady=10)
        self.quit=tk.Button(self, width=5, padx=10, pady=3)
        self.quit ["text"] = "Stop"
        self.quit ["command"] = self.stop_event
        self.quit.grid (row=3, column=2, columnspan=2, padx=4, pady=10)

    def start_event(self):
        if self.cur_process is None:
            self.cur_process=Process(target=test_main)#target function
            self.cur_process.start()

    def stop_event(self):
        if self.cur_process!=None:
            os.kill(self.cur_process.pid, signal.SIGTERM)
#            self.driver.quit()
            self.cur_process=None


default_main():# target function
    # set signal handler to SIGTERM
    defk():
        print("set new signal handler")
        try:
            driver.quit()
            # thenterminate process
        exceptionNameError: # driver is not defined
            pass#do nothing
        sys.exit()#terminate process
    signal.signal(signal.SIGTERM,k)
    # something with driver
    driver = create_driver()
defgui():
    root=tk.Tk()
    root.geometry ("400x300")
    g = GUI (master=root)
    g.mainloop()


if__name__=="__main__":
    gui()


windows python3 selenium-webdriver

2022-09-30 21:28

2 Answers

It may be a misguided answer, but rather than catching SIGTERM and cleaning the worker process yourself, how about running the worker process in daemon mode?

http://ja.pymotw.com/2/multiprocessing/basics.html#id3

If you run it in daemon mode, the worker process will automatically terminate just before the main program finishes.

Note: If you look closely at the questionnaire, it is not "Stop Button = End of Program", so this answer is not appropriate.Sorry.


2022-09-30 21:28

For Windows only, you might want to run the taskkill command with the option /f termination and /t child process included.
release Selenium chromedriver.exe from memory
Is it possible to kill a process on Windows from with Python?

Alternatively, you may need to terminate both your own child processes created in the app and WebDriver's child processes created in selenium separately.

If necessary, you should be able to run it with administrator privileges in runas.
Set administrator privileges to subprocess.check_call() in Python
Request UACelevation from within a Python script?
Run.exe file via Python as Administrator


2022-09-30 21:28

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.