所以我有一个完全独立的过程,带有已知的PID。
我想从另一个不相关的进程向它发送某种中断,以使其“正常”退出。
在 linux 中,它看起来像这样:
first_script:
def signal_handler(signum, stack):
print("SIGNAL RECIEVED")
sys.exit()
signal.signal(signal.SIGUSR1, handle_signal)
while True:
print("Im working")
第二个脚本:
known_pid = input("Enter pid")
os.kill(int(known_pid), signal.SIGUSR1)
由于Windows不支持这种方式的信号传输,因此它显然行不通,但我找不到其他简单的解决方案(经过广泛的研究)。
答案 0 :(得分:1)
考虑使用psutil,我认为它非常适合您的情况。
如document中所述,以下代码可以完成您想要的操作。尽管您可能不需要find_procs_by_name
的一部分。
import os
import signal
import psutil
def find_procs_by_name(name):
"Return a list of processes matching 'name'."
ls = []
for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
if name == p.info['name'] or \
p.info['exe'] and os.path.basename(p.info['exe']) == name or \
p.info['cmdline'] and p.info['cmdline'][0] == name:
ls.append(p)
return ls
def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
timeout=None, on_terminate=None):
"""Kill a process tree (including grandchildren) with signal
"sig" and return a (gone, still_alive) tuple.
"on_terminate", if specified, is a callabck function which is
called as soon as a child terminates.
"""
if pid == os.getpid():
raise RuntimeError("I refuse to kill myself")
parent = psutil.Process(pid)
children = parent.children(recursive=True)
if include_parent:
children.append(parent)
for p in children:
p.send_signal(sig)
gone, alive = psutil.wait_procs(children, timeout=timeout,
callback=on_terminate)
return (gone, alive)
pid = find_procs_by_name('POWERPNT.EXE')[0].pid
print(find_procs_by_name('POWERPNT.EXE')[0].pid)
kill_proc_tree(pid)
答案 1 :(得分:1)
您可以使用pywin32提供的Windows API或使用套接字对其进行入侵。
套接字解决方案又快又脏:
# waiting process
import socket
import select
import time
server = socket.socket()
server.bind(('localhost', 1337))
server.listen(5)
# this select() call returns ([server], [], [])
# if server is readable, else ([], [], []), and waits 0 seconds
while not select.select([server], [], [], 0)[0]:
print('working')
time.sleep(0.5)
# parent process
import socket
socket.create_connection(('localhost', 1337))
Windows解决方案更长但更准确地表示了问题:
# waiting process
import time
import win32event
# open an existing event by name with the required access
# (didn't work for me with EVENT_MODIFY_STATE, got "Access denied" error)
event = win32event.OpenEvent(win32event.EVENT_ALL_ACCESS, 0, "MY_NAME")
# Wait 0 seconds on the event. If event has been set, WAIT_OBJECT_0 is returned
while win32event.WaitForSingleObject(event, 0) != win32event.WAIT_OBJECT_0:
print('working')
time.sleep(0.5)
# parent process
# note that it should be run first
import win32event
import time
# create event by name
event = win32event.CreateEvent(
None, # not inherited by child processes
False, # auto-reset the event after it is set
False, # created unset
"MY_NAME", # event name
)
time.sleep(5) # wait for waiting process to start
win32event.SetEvent(event)
这只是最小的POC。建议您阅读有关event objects的信息,以找到适合您的确切解决方案。