【问题标题】:Python - creating a simple killswitch for a function that runs with multiprocessingPython - 为与多处理一起运行的函数创建一个简单的 killswitch
【发布时间】:2021-06-03 19:52:19
【问题描述】:

所以,我声称我基本了解 Asyncio、多处理、线程等的工作原理。我也知道如何听击键 - 这个网站上有很多很好的例子。

但是我无法将两者合二为一。我有一个程序在循环中连续运行,直到它遇到某些停止的情况。在这些情况下,它使用Multiprocessing.Queue() 提示用户输入是否应该继续。

所有这些都有效,到目前为止一切顺利。现在我想在这里添加第二个捕获案例:程序一旦开始运行,一旦我按下某个按钮(比如说 Escape),它应该立即停止工作。

这是我的程序非常简单的版本:

test.py:

from test3 import Counter
from multiprocessing import Process,  Queue
import sys

def main(q, passed_variable):
    foo = Counter()
    p1 = Process(target=foo.counting, args=(q,passed_variable))
    p1.start()
    p1.join()
    if q.get() == False:
        x = input("Keep going?")
        print(x)
        if x == "y":
            main(q, user_Input)
        else:
            sys.exit()

if __name__ == "__main__":
    q = Queue()

    user_Input = ("What you want from me, man?")
    print("Starting")
    main(q, passed_variable=user_Input)

test3.py:

import time

class Counter:
    def counting(self, q, user_input):
        x = 0
        while True:
            print(str(x) + " " + user_input)

            if x == 4:
                q.put(False)
                break

            time.sleep(1)
            x += 1

我尝试了所有我能想到的方法,但在任何情况下都没有得到想要的结果,而且我在这里找到的任何问题都无法在这种特定情况下帮助我。

【问题讨论】:

  • 您希望将multiprocessing.Event 作为参数传递,然后在父进程中调用.set() 并在子进程的函数中检查.is_set()

标签: python multiprocessing keystroke


【解决方案1】:

您可以使用keyboard 解决此问题,然后创建第二个Queue()

from test3 import Counter
from multiprocessing import Process,  Queue
import sys
import keyboard

def main(q, queue2, passed_variable):
    foo = Counter()
    p1 = Process(target=foo.counting, args=(q,passed_variable))
    p1.start()

    p2 = Process(target=keyCatcher, args=(queue2,))
    p2.start()

    if queue2.get() == False:
        p1.terminate()

        print("Terminating Programm")
        sys.exit()

    if q.get() == False:
        x = input("Keep going?")
        print(x)
        if x == "y":
            main(q, queue2, user_Input)
        else:
            sys.exit()

def keyCatcher(queue2):
    while True:
        if keyboard.is_pressed('q'):  # if key 'q' is pressed
            queue2.put(False)


if __name__ == "__main__":
    q = Queue()
    queue2 = Queue()

    user_Input = ("What you want from me, man?")
    print("Starting")
    main(q, queue2, passed_variable=user_Input)

【讨论】:

    【解决方案2】:

    关键是:

        p1.start()
        p1.join()
    

    这意味着在main() 启动 p1 之后,它会等待它完成。所以在处理过程中没有机会打断它。

    你需要:

    1. 等待 p1 完成
    2. 等待时,看看主进程是否得到一个'q'
    3. 如果主进程得到一个 'q',停止它。

    类似:

        p1.start()
        while p1.is_alive():
            k = keyboard.read_key()
            if k == 'q':
                p1.terminate()
    

    【讨论】:

    • 我也有类似的问题,我明白你的意思,但是我该如何解决呢? .join() 是这里的问题吗?您将如何更改 OP 代码以使其不等待 p1 完成?
    • 感谢您的回复 - 如果这不可能,那么我该怎么做才能让它发挥作用?
    猜你喜欢
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2016-07-02
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多