【问题标题】:How to terminate a process that the script starts by command line?如何终止脚本通过命令行启动的进程?
【发布时间】:2021-08-24 10:50:05
【问题描述】:

我有一个接收多个参数的脚本。主线程成为服务器,参数是运行客户端的命令行字符串。一旦服务器从客户端收到它想要的东西,我想终止它们。除此之外,我无法控制客户。它们可以用其他语言编写,通信结束后不需要做任何清理操作,我需要确保它们终止。

我试图将它们设为threading.Threads,我称之为system(run_string)。但是,python 不支持直接杀死它们。所以我尝试使用ctypes.pythonapi.PyThreadState_SetAsyncExc 在内部引发异常。出于某种原因,这只会在system() 调用完成后提示异常,即在客户端自行终止之后。

>>>main.py
(...)
def raise_exception(t):
    thread_id = get_thread_id(t)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
        ctypes.c_long(thread_id),
        ctypes.py_object(SystemExit)
    )
    if (res == 0):
        raise ValueError("Invalid thread ID. Cannot terminate.")
    elif (res != 1):
        ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 0)
        raise SystemError("Bad thing happened. Cannot terminate.")


def f(s):
    try:
        system(s) # subprocess.run(s) yields the same result
    finally:
        print("Terminating.")


if (__name__ == "__main__"):
    t = threading.Thread(target=f, args=(ttest_s,))
    t.start()
    time.sleep(1)
    raise_exception(t)
    t.join()
>>>ttest.py
(...)
if (__name__ == "__main__"):
    for i in range(4):
        print(f"{i} second(s) passed.")
        sleep(1)
>>>python3 main.py
0 second(s) passed.
1 second(s) passed.
2 second(s) passed.
3 second(s) passed.
Terminating.

为什么会这样?我该如何解决?

【问题讨论】:

    标签: python python-3.x multithreading shell command-line


    【解决方案1】:

    线程似乎不支持这个特定问题。以下工作正常:

    t = subprocess.Popen(ttest_s)
    time.sleep(1)
    t.terminate()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-14
      • 2013-06-18
      • 1970-01-01
      • 1970-01-01
      • 2010-11-28
      相关资源
      最近更新 更多