wxpython使用多进程,wxPython非阻塞GUI线程和多处理?

这篇博客讨论了Python中多线程与多进程的区别。作者发现,为了不阻塞GUI,必须先创建线程再在其中启动多进程,而直接使用多进程会导致GUI被阻塞。文章解释了多线程主要用于I/O,而多进程可以在操作系统级别上并行运行,不共享内存空间,适合于CPU密集型任务。对于GUI应用,通常使用多线程来处理不同部分,避免单一操作锁死整个界面。作者指出问题在于混淆了多进程和多线程的基本概念。
摘要由CSDN通过智能技术生成

Python 2.7.3 x64

wxPython 2.8 x64

Been reading quite a bit on python threading and multiprocessing, particularly some articles by Doug Hellmann, which have helped tremendously. However, I'm confused about one thing...

I thought the Python multiprocessing module was more-or-less a drop-in replacement for the threading module, excepting that args must be picklable, but I'm finding that in order not to block my GUI, I must first create a new thread with threading.Thread then multiprocess within that thread with multiprocessing.Process. This works, and works well, but it seems a bit kludgey to me.

If I try to directly multiprocess without first threading, then my GUI still blocks until the multiprocessing job is done. Is that working as designed, or am I missing something fundamental about the multiprocessing module?

If examples are needed, I can provide them.

Thanks,

-RMWChaos

An example was requested...

Assuming that onProcess() is triggered by a button in the GUI, this blocks the GUI...

import time

import multiprocessing as mp

def myWorker(a, b):

time.sleep(0.1)

print '{} * {} = {}'.format(a, b, a*b)

def onProcess(event):

jobs = mp.cpu_count() * 2

a = 5

b = 10

for job in range(jobs):

mp.Process(target = myWorker, args = (a, b,)).start()

While this doesn't...

import time

import multiprocessing as mp

import threading as th

def myWorker(a, b):

time.sleep(0.1)

print '{} * {} = {}'.format(a, b, a*b)

def onProcess(event):

a = 5

b = 10

th.Thread(target = myThread, args = [a, b,]).start()

def myThread(a, b):

jobs = mp.cpu_count() * 2

for job in range(jobs):

mp.Process(target = myWorker, args = (a, b,)).start()

解决方案

Multi-threading and multi-processing are fundamentally different.

Threads are used for i/o for the most part. When you make a new thread it is contained within the same process as the program you spawned the thread from. What that means is that it shares memory space with the program, but they (the program and the thread) cannot run in parallel (also look up GIL).

Multi-processing on the other hand spawns a new process on the OS level. This new process can run in parallel with the pre-existing process, but it does not share memory space with the program that spawned it. This is more useful when the code you want to speed up is not i/o related but actual processor intensive computation.

For a gui, you mostly want to use threading for different parts of the gui so that running something in one part of the gui does not lock up your entire gui until that handling ends.

Without code it is hard to tell, but I believe you should not particularly need to spawn a process within the new thread, but instead just have that thread handle the processing. However, if that thread needs to handle intensive computational type of processing as opposed to lots of i/o, then you would want to start a process to handle that.

I believe that most of your problem lies in misunderstanding multi-processing vs multithreading.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 wxPython 创建多进程的时候,你可以使用 Python 的内置模块 `multiprocessing` 来实现。下面是一个简单的示例代码,演示了如何在 wxPython 创建多个进程: ```python import wx import multiprocessing class MyFrame(wx.Frame): def __init__(self, parent, title): super(MyFrame, self).__init__(parent, title=title) self.panel = wx.Panel(self) self.button = wx.Button(self.panel, label="Start Processes") self.Bind(wx.EVT_BUTTON, self.on_button_click, self.button) self.sizer = wx.BoxSizer(wx.VERTICAL) self.sizer.Add(self.button, 0, wx.ALIGN_CENTER|wx.ALL, 5) self.panel.SetSizer(self.sizer) def on_button_click(self, event): processes = [] for i in range(5): process = multiprocessing.Process(target=self.run_process, args=(i,)) processes.append(process) process.start() for process in processes: process.join() def run_process(self, num): print(f"Process {num} started") if __name__ == "__main__": app = wx.App() frame = MyFrame(None, "Multi-Processing Example") frame.Show() app.MainLoop() ``` 在这个例子,我们创建了一个简单的 wxPython 窗口,并在窗口添加了一个按钮。当按钮被点击时,将启动5个进程,每个进程执行 `run_process` 方法。在这个方法,我们简单地打印出进程的编号。 请注意,在多进程编程,需要小心处理 GUI 元素的更新。在上面的示例,我们只是简单地打印了一些文本,而没有更新 GUI 元素。如果你需要更新 GUI 元素,你可能需要使用线程间通信来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值