Я пытаюсь использовать модуль многопроцессорности в цикле for
внутри класса PyQt. К сожалению, этот скрипт дает мне много ошибок. Вот сценарий, который просто отображает кнопку «Запустить» и запускает процесс в цикле, который печатает значение.RuntimeError и IOError при использовании многопроцессорности в скрипте PyQt
import multiprocessing
from PyQt4 import QtGui
import sys
class SurfViewer(QtGui.QMainWindow):
def __init__(self, parent=None):
super(SurfViewer, self).__init__()
self.parent = parent
self.centralWidget = QtGui.QWidget()
self.setCentralWidget(self.centralWidget)
self.mainHBOX_param_scene = QtGui.QHBoxLayout()
self.Button_Run = QtGui.QPushButton('Run')
self.mainHBOX_param_scene.addWidget(self.Button_Run)
self.centralWidget.setLayout(self.mainHBOX_param_scene)
self.Button_Run.clicked.connect(self.Runclick)
def Runclick(self):
for i in range(5):
p = multiprocessing.Process(target=self.mp_worker,args=(i,))
p.start()
def mp_worker(self,a):
print('a:' + str(a))
return
def main():
app = QtGui.QApplication(sys.argv)
ex = SurfViewer(app)
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Я не понимаю, что я здесь делаю неправильно, так как ниже код работает хорошо:
import multiprocessing
class maclass():
def __init__(self,):
for i in range(5):
p = multiprocessing.Process(target=self.mp_worker , args=(i,))
p.start()
def mp_worker(self,a):
print('a:' +str(a))
return
def main():
maclass()
if __name__ == '__main__':
main()
Единственная разница в том, что делается нескольких процессов в Button_Run.clicked. event
.
Ошибки я получаю (от первого сценария):
Traceback (most recent call last):
File "", line 1, in
File "C:\Anaconda2\lib\multiprocessing\forking.py", line 381, in main self = load(from_parent)
File "C:\Anaconda2\lib\pickle.py", line 1384, in load return Unpickler(file).load()
File "C:\Anaconda2\lib\pickle.py", line 864, in load dispatchkey
File "C:\Anaconda2\lib\pickle.py", line 1221, in load_build setstate = getattr(inst, "setstate", None)
RuntimeError: super-class init() of type QPushButton was never called
Но я также получаю другую ошибку, когда я пытаюсь использовать многопроцессный в моем большом приложении, например:
File "C:\Anaconda2\lib\pickle.py", line 492, in save_string
self.write(BINSTRING + pack(" i", n) + obj)
IOError: [Errno 32] Broken pipe
Возможно, это может быть связано с первой ошибкой.
Кто-нибудь уже видел решение этой проблемы?
Редактировать: Я попытался использовать приведенный ниже пример @ImportanceOfBeingErnest. Так вот новый код:
import multiprocessing
from PyQt4 import QtGui
import sys
class maclass():
def __init__(self,):
pass
def start(self, n):
lfp=[]
for i in range(n):
recv_end, send_end = multiprocessing.Pipe()
p = multiprocessing.Process(target=self.mp_worker , args=(i,send_end))
p.start()
send_end.close()
lfp.append(recv_end.recv())
recv_end.close()
print(i, lfp)
#p.join()
def mp_worker(self,a,send_end):
print('a:' +str(a))
send_end.send(a)
return
class SurfViewer(QtGui.QMainWindow):
def __init__(self, parent=None):
super(SurfViewer, self).__init__()
self.parent = parent
self.centralWidget = QtGui.QWidget()
self.setCentralWidget(self.centralWidget)
self.mainHBOX_param_scene = QtGui.QHBoxLayout()
self.Button_Run = QtGui.QPushButton('Run')
self.mainHBOX_param_scene.addWidget(self.Button_Run)
self.centralWidget.setLayout(self.mainHBOX_param_scene)
self.worker = maclass()
self.Button_Run.clicked.connect(self.start)
def start(self):
for k in range(5):
self.worker.start(4)
def main():
app = QtGui.QApplication(sys.argv)
ex = SurfViewer(app)
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
В этом случае, я хотел бы получить результат от работника с recv_end, send_end = multiprocessing.Pipe()
. Этот код отлично работает в том смысле, что я получаю правильный результат. К сожалению, кажется, что я теряю способность многопроцессорности. Я явно делаю что-то не так с трубой, но я не могу понять, что это такое.
Ваша рабочая функция - это метод окна Qt. Это означает, что каждый новый процесс должен иметь это (или копию) этого окна. Windows не может быть отобрана и передана в новое окно. Вы должны отделить своего рабочего от пользовательского интерфейса. –
Спасибо, что ответили. Это ответ, который я не хотел ...;) , потому что я хотел бы использовать рабочего как часть класса для изменения некоторых членов этого класса. – ymmx