我正在开发一些旨在作为独立应用程序分发的小python。
我想使用并行python,因为它可以帮助我更快地执行。
通过以下示例,当我通过pyinstaller创建可执行文件时,当它调用pp.Server()
时,它会启动一个新窗口。当我关闭新窗口时,会出现管道错误。
以下是出现此问题的脚本示例:
import pp, os, sys, multiprocessing
from bs4 import BeautifulSoup as Soup
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(188, 119)
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.pushButton = QtGui.QPushButton(self.centralwidget)
self.pushButton.setText(QtGui.QApplication.translate("MainWindow", "PushButton", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setObjectName(_fromUtf8("pushButton"))
self.horizontalLayout.addWidget(self.pushButton)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
pass
class TestClass(object):
__slots__ = ('var')
def __init__(self):
self.var = 'a string'
def doSomething (self, input_string) :
self.var = input_string
class PPTask (object) :
def __init__ (self) :
pass
def ppTask(self, file = '') :
html = open(file).read()
soup = Soup(html)
ret_results = []
for i in xrange(10) :
tc = parallel_tests.TestClass()
s = str(soup.title.string) # if it is not put in string it won't work in multithreading....
#~ tc.doSomething(soup.title.string) # this doesn't works
tc.doSomething(s) # this works if s is a string not a "soup string"
ret_results.append(tc)
return ret_results
class Window(QtGui.QMainWindow) :
def __init__ (self, parent = None) :
QtGui.QMainWindow.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.createSignals()
def createSignals(self):
QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL("clicked()"), self.doItBaby)
def doItBaby (self) :
print('it works until here ')
try :
job_server = pp.Server() # this creates a new mainwindow !
except Exception, e :
print("I supposed you've just closed the new window created haven't you? " + str(e))
job_list = []
results = []
cmpt = 0
for i in xrange(100) :
pt = PPTask()
job_list.append(job_server.submit(pt.ppTask, ('anHTMfile.htm',),modules = ("parallel_tests","from bs4 import BeautifulSoup as Soup")))
for job in job_list :
results.append(job())
for result in results :
for item in result :
print 'cmpt = ' + str(cmpt)
cmpt += 1
print item.var
if __name__ == '__main__':
multiprocessing.freeze_support()
current_dir = os.getcwd()
app = QtGui.QApplication(sys.argv)
ui = Window()
ui.show()
sys.exit(app.exec_())
我尝试添加freeze_support(),但它没有像我预期的那样有用。
如果有人能帮助我,我将不胜感激。
答案 0 :(得分:0)
我还没有尝试过,但可能是因为如果关闭新窗口,就不再有对象的引用了,它会被垃圾收集。
无论如何,在gui中发生所有这些事情都不是很好的设计。
答案 1 :(得分:0)
似乎并行python没有正式的冻结支持。其他人似乎通过py2exe遇到了同样的问题:
http://www.parallelpython.com/component/option,com_smf/Itemid,1/topic,161.0/wap2,wap2
如果您只是使用该模块,则使用多处理冻结会起作用,但它对PP模块没有影响。
问题是它再次启动您的主应用程序而不是工作人员,因此您最终会看到应用程序的另一个实例。 PP使用IPC进行通信,因此当你杀死窗口时,你会杀死它的通信管道并抱怨PP。