如何在 Python 上进行多处理
我正在使用 tkinter 用 Python 编写一个小程序来使多个对象移动。
首先,我尝试使用线程创建 2 个对象并让它们同时移动。因此,我复制/粘贴创建和移动 1 个对象的函数,然后在 2 个线程中执行这两个函数。
现在我想尝试选择移动的对象数量,所以我得到了 1 个函数,并且我想同时执行多次。线程不再是可能的。
所以我尝试了多重处理,但遇到了一个问题:它什么也没做...... 我用一个简单的代码重新创建了这个问题:
import multiprocessing
def pr(number):
print(number)
p = multiprocessing.Process(target=pr,args=(40,))
p.start()
它返回绝对没有任何内容,没有打印任何内容。我认为多重处理不是完成我想要的事情的足够工具,但我不明白这段代码的问题。
PS:我在 Windows 上使用 IDLE Python 3.7.2
I'm making a little program in Python using tkinter to make multiple objects move.
First I tried Threading to create 2 objects and make them move at the same time. So I copy/paste the function that create and move 1 object and then execute the two functions in 2 threads.
Now I wanted to try to choose the number of object moving so I got 1 function and I want to execute it multiple times at the same time. Threading was no longer a possibility.
So I tried multiprocessing and I got a problem : it does nothing...
I recreated the problem with a simple code :
import multiprocessing
def pr(number):
print(number)
p = multiprocessing.Process(target=pr,args=(40,))
p.start()
It returns an absolute nothing, nothing is printed. I think multiprocessing is not the adequate tool to do what I want but I don't understand the problem of this code.
PS : I'm using IDLE Python 3.7.2 on Windows
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这篇文章本质上是Can multiprocessing Process class be run from IDLE<的重复/a>.我通过搜索“[python-idle] multiprocessing”找到了它。我在这里给出了之前答案的修订和扩展版本。
正如 @Booboo 所说,至少在 Windows 上,也许在 macOS 上,需要一个
if __name __ == '__main__':
块。有了这个,在 Windows 上从 IDLE 启动时,multiprocessing
本身就可以正常运行。打印失败。当 multiprocessing 启动一个新的 python 进程时,它会将当前进程 sys.__stdout__ 复制到 sys.__stdout__ 和 sys.stdout< /code> 在新进程中。默认情况下,
print
将请求的文本写入sys.stdout
。当 GUI 程序从图标或终端以外的其他方式启动时,
sys.__stdout__
和sys.stdout
被初始化为None
,在至少在 Windows 上。 IDLE 将sys.stdout
替换为一个对象,该对象的write
方法将文本发送到 IDLE 的 Shell。复制 IDLE 特定的 sys.stdout 是没有用的,因为它不起作用。如果您在 Windows 上使用 py -midlelib 从命令行启动 IDLE,则 sys 属性将被初始化为将文本发送到控制台/终端的普通 python io 对象。 IDLE 仅替换 sys.stdout,因此多处理可以将工作
sys.__stdout__
io
对象复制到新进程的两个 sys 属性。默认情况下,“print”将打印到控制台,如此例所示。打印到 CommandPrompt 显然不是很好,但它是您可以使用非 IDLE 代码执行的最佳操作。在您的特定情况下,想要为 tkinter 对象设置动画(大概在 tkinter 画布上),您应该在循环后使用 tk/tkinter 而不是多重处理。 IDLE 专为开发 tkinter 程序而设计。搜索
[tkinter] animate
会得到几百次点击。This post is essentially a duplicate of Can multiprocessing Process class be run from IDLE. I found it by searching SO for "[python-idle] multiprocessing". I give a revised and expanded version of my previous answer here.
As @Booboo said, an
if __name __ == '__main__':
block is needed, at least on Windows and perhaps macOS. With that present,multiprocessing
itself runs fine when started from IDLE on Windows.The failure is with printing. When
multiprocessing
starts a new python process, it copies the current processsys.__stdout__
to bothsys.__stdout__
andsys.stdout
in the new process. By default,print
writes the requested text tosys.stdout
.When a GUI program is started from an icon or somehow other than a terminal,
sys.__stdout__
andsys.stdout
are initialized toNone
, at least on Windows. IDLE replacessys.stdout
with an object whosewrite
method sends text to IDLE's Shell. It would be useless to copy the IDLE specific sys.stdout as it would not work.If, instead you start IDLE from a command line with, on Windows,
py -m idlelib
, the sys attributes are instead initialized to a normal python io object that sends text to the console/terminal. IDLE only replaces sys.stdout, so multiprocessing can copy the workingsys.__stdout__
io
object to both sys attributes of the new process. By default, 'print' will then print to the console, as in this example.Printing to CommandPrompt is obviously not great, but it is the best you can do with non-IDLE code. In your particular case, of wanting to animate tkinter objects (presumably on a tkinter canvas), you should use tk/tkinter after loops instead of multiprocessing. IDLE is designed for developing tkinter programs. Searching SO for
[tkinter] animate
gives a few hundred hits.正如 Terry Jan Reedy 指出的那样,我关于无法在 IDLE 下运行多处理的评论显然是错误的。
IDLE 的问题与尝试从 Jupyter Notebook 等环境进行多重处理时遇到的问题相同。也就是说,除了您的工作函数(在您的情况下,
pr
)必须位于导入的单独模块中之外,它是可以完成的。如果不这样做,则会出现以下异常:不幸的是,通过从 Windows 开始菜单启动 IDLE,永远不会看到该异常消息。如果 IDLE 是从命令提示符启动的,而不是使用 ...
...,则
AttributeError
异常将显示在命令提示符控制台上。因此:
pr
函数放在某个目录中的文件中,例如 pr.py。那么你的程序就变成了:
My comment about not being able to run multiprocessing under IDLE was clearly wrong as pointed out by Terry Jan Reedy.
The problem with IDLE is the same problem one has in trying to do multiprocessing from an environment such as Jupyter Notebook. That is, it can be done except that your worker function,
pr
in your case, must be in a separate module that is imported. If you do not do this, then you get the following exception:Unfortunately, by starting IDLE from the Windows start menu, that exception message was never seen. Had IDLE been started from a command prompt instead with ...
... then the
AttributeError
exception would have been displayed on your command prompt console.So:
pr
function in a file, for example pr.py, in some directory.Then your program becomes: