python-3.x - 如何在 Python 3 和 PyQt5 中实现多核处理?

标签 python-3.x image-processing multicore pyqt5 python-multiprocessing

背景: 我正在尝试在 python 3.4 PyQT5 应用程序中实现多核处理。

在应用程序中,我有帧的 numpy.ndarrays,把它想象成一个 [n,m,t] 数组。我需要处理每个 [n,m,:] 数组,并且使用多核会线性加快我的进程。

我玩过 multiprocessing 并使用部分示例脚本制作了一个简单的脚本,并给了我以下想法:

简单无 GUI 代码 :

import multiprocessing as mp
import numpy

aa = numpy.random.rand(4,2,3)

def random_function(x):
    return x,x**3

if __name__ == '__main__':
    pool = mp.Pool(processes=4)

    #with apply_asynch

    #results = [pool.apply_async(cube, args=(aa[:,:,x],)) for x in range(0,aa.shape[2])]
    #output = [p.get() for p in results]
    #test_va = numpy.asarray( output)


    #with apply

    results = [pool.apply(random_function, args=(aa[:,:,x],)) for x in range(0,aa.shape[2])]
    test_va = numpy.asarray( results)

这有效并且可以满足我的需要。

问题: 现在,当我在 PyQT5 中实现此功能时,我会遇到“酸洗”问题。因此,按照 PyQT4 here 的建议,我制作了一个简单的 GUI,生成一个线程并使用多处理。结果,我将相同的 GUI 复制了 4 次,但它似乎不起作用。

PyQT5 GUI 非工作代码:
import sys, time
from PyQt5.QtCore import * 
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

import multiprocessing as mp
import numpy

class WorkThread(QThread):
    finished = pyqtSignal(int,object)


    def __del__(self):
      self.wait()

    def cube(x):
        return x,x**3

    def run(self):
        aa = numpy.random.rand(4,2,3)

        pool = mp.Pool(processes=4)
        results = [pool.apply_async(self.cube, args=(aa[:,:,x],)) for x in range(0,aa.shape[2])]
        output = [p.get() for p in results]
        test_va = numpy.asarray( output)

        for i in range(5):

            QThread.sleep(0.3) # artificial time delay

            self.finished.emit(i,test_va)




class test_multicore(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.setGeometry(300, 300, 280, 600)
        self.setWindowTitle('Qthreads and multicore')

        self.layout = QVBoxLayout(self)

        self.testButton = QPushButton("test")
        self.testButton.clicked.connect(self.test)

        self.listwidget = QListWidget(self)

        self.layout.addWidget(self.testButton)
        self.layout.addWidget(self.listwidget)
        self.threadPool = []

    def add(self, text,random_matrix): 
        """ Add item to list widget """
        print ("Add: " + str(text) +str(random_matrix))
        self.listwidget.addItem(str(text))
        self.listwidget.sortItems()

    def addBatch(self,text="text",iters=6,delay=0.3): 
        """ Add several items to list widget """
        for i in range(iters):
            time.sleep(delay) # artificial time delay
            self.add(text+" "+str(i), 0)


    def test(self):
        self.listwidget.clear()

        self.addBatch("_non_thread_entries",iters=6,delay=0.3)




        self.workThread = WorkThread()
        self.workThread.finished[int,object].connect(self.add)


        self.workThread.start()






# run
app = QApplication(sys.argv)
test = test_multicore()
test.show()
app.exec_()

我也尝试过使用 Qobject 并将其传递给带有 moveToThread 的线程,但再次遇到相同的问题。

问题:
如何在我的 Python 3.4 PyQT5 应用程序中实现多核处理?考虑到我将在 Windows 和 Mac 上使用 cx_freeze 进行部署。

最佳答案

添加

if __name__ == '__main__':

在环境创建之前确保应用程序创建一次。

这是多处理 pyqt5 python 3.4 的工作代码/示例。
import sys, time
from PyQt5.QtCore import * 
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

import multiprocessing as mp
import numpy

class WorkThread(QThread):
    finished = pyqtSignal(int,object)


    def __del__(self):
      self.wait()

    def cube(self,x):
        return x,x**3

    def run(self):
        aa = numpy.random.rand(4,2,3)

        pool = mp.Pool(processes=4)
        results = [pool.apply_async(self.cube, args=(aa[:,:,x],)) for x in range(0,aa.shape[2])]
        output = [p.get() for p in results]
        test_va = numpy.asarray( output)

        for i in range(5):

            QThread.sleep(0.3) # artificial time delay

            self.finished.emit(i,test_va)




class test_multicore(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.setGeometry(300, 300, 280, 600)
        self.setWindowTitle('Qthreads and multicore')

        self.layout = QVBoxLayout(self)

        self.testButton = QPushButton("test")
        self.testButton.clicked.connect(self.test)

        self.listwidget = QListWidget(self)

        self.layout.addWidget(self.testButton)
        self.layout.addWidget(self.listwidget)
        self.threadPool = []

    def add(self, text,random_matrix): 
        """ Add item to list widget """
        print ("Add: " + str(text) +str(random_matrix))
        self.listwidget.addItem(str(text))
        self.listwidget.sortItems()

    def addBatch(self,text="text",iters=6,delay=0.3): 
        """ Add several items to list widget """
        for i in range(iters):
            time.sleep(delay) # artificial time delay
            self.add(text+" "+str(i), 0)


    def test(self):
        self.listwidget.clear()

        self.addBatch("_non_thread_entries",iters=6,delay=0.3)




        self.workThread = WorkThread()
        self.workThread.finished[int,object].connect(self.add)


        self.workThread.start()






# run
if __name__ == '__main__':
    app = QApplication(sys.argv)
    test = test_multicore()
    test.show()
    app.exec_()

使用 apply_asynch 替代:
results = [pool.apply_async(cube, args=(aa[:,:,x],)) for x in range(0,aa.shape[2])]
output = [p.get() for p in results]
test_va = numpy.asarray( output)

关于python-3.x - 如何在 Python 3 和 PyQt5 中实现多核处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29310824/

相关文章:

linux - SMP 如何处理中断?

arm - 如何访问多核 ARM CPU 的程序计数器寄存器

android - 如何从 OpenCV 返回图像并在 Android Java 代码中显示它?

matlab - Matlab中级联训练 "trainCascadeObjectDetector"错误

python - 如何使用 Python 在 SPSS 中设置可变宽度和小数?

csv - 将子进程的输出转换为 csv.reader 对象

java - 如何在java中找到两点之间的每个像素?

.net - 为什么.net 4.5 中的多核 JIT 不是 "on by default"?

python - Next on generators 不会从上次调用恢复

python - numpy 已与 Anaconda 一起安装,但我收到 ImportError(DLL 加载失败 : The specified module could not be found)