【问题标题】:How to rewrite this multiprocessing code for Windows?如何为 Windows 重写这个多处理代码?
【发布时间】:2019-10-05 23:19:42
【问题描述】:

我目前正在使用多处理,因此我可以在运行其他代码时获取用户输入。这个版本的代码对我来说在 ubuntu 19.04 上运行,但对我的朋友来说它在 windows 上不起作用。

import getch
import time
from multiprocessing import Process, Queue

prev_user_input = ' '
user_input = ' '


# Getting input from the user
queue = Queue(1)

def get_input():
    char = ' '
    while char != 'x':
        char = getch.getch()
        queue.put(char)

# Starting the process that gets user input
proc = Process(target=get_input)
proc.start()


while True:

    # Getting the users last input
    while not queue.empty():
        user_input = queue.get()

    # Only print user_input if it changes
    if prev_user_input != user_input:
        print(user_input)
        prev_user_input = user_input

    time.sleep(1/10)

如何让这段代码在 Windows 上运行?

此外,用户输入滞后一个输入。如果用户按下一个按钮,它只会在他按下另一个按钮后打印。有关如何解决此问题的解决方案也会有所帮助。

编辑 1: 他使用的是 Python 3.7.4,而我使用的是 3.7.3。

我按照建议尝试了这段代码

import msvcrt
import time
from multiprocessing import Process, Queue

prev_user_input = ' '
user_input = ' '


# Getting input from the user
queue = Queue(1)

def get_input():
    char = ' '
    while char != 'x':
        char = msvcrt.getch()
        queue.put(char)

# Starting the process that gets user input
if __name__ == '__main__':
    proc = Process(target=get_input)
    proc.start()


    while True:

        # Getting the users last input
        while not queue.empty():
            user_input = queue.get()

        # Only print user_input if it changes
        if prev_user_input != user_input:
            print(user_input)
            prev_user_input = user_input

        time.sleep(1/10)

但是没有打印任何字符。

编辑 2: 我在 Windows 上使用 msvcrt 模块,在 ubuntu 上使用 getch 模块。很抱歉没有在帖子前面说清楚。

【问题讨论】:

  • 尝试在# Starting the process that gets user input 行之前添加一个if __name__ == '__main__': 行——同时缩进该行后面的所有代码。在“安全导入主模块”小节中,Programming Guidelines 中的 multiprocessing 模块解释了这样做的必要性。
  • 你在每台机器上使用了哪些版本的python?
  • @martineau 我试过这样做。现在程序不会崩溃,但它不会显示与在 linux 中相同的行为,即打印字符。
  • @AnnKilzer 我正在使用 3.7.3,他正在使用 3.7.4。
  • 我不明白使用msvcrt.getch() 是如何在 Windows 以外的任何东西上工作的——但你声称它在 ubuntu 上可以工作。

标签: python python-3.x linux windows multiprocessing


【解决方案1】:

以下内容适用于 Windows。它包含了我在您的问题下在我的 cmets 中建议的所有更改,包括关于单独内存空间的最后一个更改。

类似的东西也应该在 ubuntu 下使用 getch() 版本,虽然我没有测试过。 on 主进程创建Queue 并将其作为参数传递给get_input() 目标函数,因此它们都使用同一个对象来交换数据。

我还将decode()bytes 对象从msvcrt.getch() 返回以将其转换为(1 个字符)Unicode UTF-8 字符串。

import msvcrt
import time
from multiprocessing import Process, Queue

prev_user_input = ' '
user_input = ' '


def get_input(queue):
    char = ' '
    while char != b'x':
        char = msvcrt.getch()
        queue.put(char.decode())  # Convert to utf-8 string.

if __name__ == '__main__':
    # Getting input from the user.
    queue = Queue(1)

    # Starting the process that gets user input.
    proc = Process(target=get_input, args=(queue,))
    proc.start()


    while True:

        # Getting the users last input
        while not queue.empty():
            user_input = queue.get()

        # Only print user_input if it changes
        if prev_user_input != user_input:
            print(user_input)
            prev_user_input = user_input

        time.sleep(1/10)

更新

要隐藏操作系统差异并使代码更具可移植性,您可以执行importing,如下所示,这还允许您像在问题代码中所做的那样定义get_input() 函数:

import os
import time
from multiprocessing import Process, Queue

try:
    import msvcrt
    getch = msvcrt.getwch  # Wide char variant of getch() that returns Unicode.
except ModuleNotFoundError:  # Not Windows OS - no msvcrt.
    from getch import getch

prev_user_input = ' '
user_input = ' '


def get_input(queue):
    char = ' '
    while char != 'x':
        char = getch()
        queue.put(char)


if __name__ == '__main__':
    # For getting input from the user.
    queue = Queue(1)

    # Starting the process that gets user input.

    .
    .
    .

【讨论】:

  • 此解决方案有效,非常感谢。 'x'之前的b有什么意义?另外,为什么在使用 char.decode() 时打印字符没有任何滞后,但在不使用时却没有? char.decode() 在 Windows 上也可以完美运行,但在 ubuntu 上我得到一个错误。 AttributeError: 'str' object has no attribute 'decode'这是为什么呢?
  • b 字符串前缀表示该字面量是内置bytes 类的实例,这是msvcrt.getch() 返回的值的类型。 decode() 调用将其转换为常规 Python 字符串,该字符串采用 utf-8 Unicode 编码。如果您使用 msvcrt.getwch()getch() 的“宽”字符变体),则所有这些都不是必需的,因为它返回 Unicode。显然 ubuntu 上的 getch() 返回 utf-8 字符串,所以它也不需要这样做。
猜你喜欢
  • 1970-01-01
  • 2015-06-26
  • 1970-01-01
  • 2016-03-17
  • 1970-01-01
  • 1970-01-01
  • 2017-07-07
  • 1970-01-01
  • 2011-06-28
相关资源
最近更新 更多