Python:多处理解除行为
有一个class属性self.class\u变量。单击“按”将一个、两个和三个附加到class_变量列表按钮,将调用一个外部到MainWindow类externalFunc函数,该函数用于附加“一”、“二”、“三”。一行:Python:多处理解除行为,python,multithreading,multiprocessing,Python,Multithreading,Multiprocessing,有一个class属性self.class\u变量。单击“按”将一个、两个和三个附加到class_变量列表按钮,将调用一个外部到MainWindow类externalFunc函数,该函数用于附加“一”、“二”、“三”。一行: externalFunc(str(self.i)) 用于直接调用externalFunc将数字追加到同一self.class_变量列表中 按“按以打印class_变量列表”打印self.class_变量的内容。我无法解释为什么 pool.map_async( externa
externalFunc(str(self.i))
用于直接调用externalFunc将数字追加到同一self.class_变量列表中
按“按以打印class_变量列表”打印self.class_变量的内容。我无法解释为什么
pool.map_async( externalFunc, self.myList )
对self.class_变量没有影响。self.class_变量的值保持不变。
请告知
from PyQt4 import QtCore, QtGui
from multiprocessing import Pool
def externalFunc(arg):
window.setAttrbitute(arg)
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.main_layout = QtGui.QVBoxLayout()
self.class_variable=['InitialValue']
self.myList=['One','Two','Three']
self.i=0
print_button = QtGui.QPushButton('Press to print class_variable list')
print_button.clicked.connect(self.printVariable)
self.main_layout.addWidget(print_button)
ok_button = QtGui.QPushButton("Press to append One, Two and Three to class_variable list")
ok_button.clicked.connect(self.append_from_external_using_multi)
self.main_layout.addWidget(ok_button)
central_widget = QtGui.QWidget()
central_widget.setLayout(self.main_layout)
self.setCentralWidget(central_widget)
def setAttrbitute(self, arg):
print "Appending arg to class_variable: ", arg
self.class_variable.append(arg)
def append_from_external_using_multi(self):
# calling external function dirctly:
externalFunc(str(self.i))
# calling external function via pool.map_async:
pool = Pool(processes=3)
pool.map_async( externalFunc, self.myList )
self.i+=1
def printVariable(self, arg):
print "\n\t self.class_variable = ", self.class_variable
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.resize(480, 320)
window.show()
sys.exit(app.exec_())
根据J.F.Sebastian发布的建议修订工作守则
from PyQt4 import QtCore, QtGui
import multiprocessing as mp
def externalFunc(arg):
window.setAttrbitute(arg)
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.main_layout = QtGui.QVBoxLayout()
self.class_variable=manager.list(['InitialValue'])
self.myList=['One','Two','Three']
self.i=0
print_button = QtGui.QPushButton('Press to print class_variable list')
print_button.clicked.connect(self.printVariable)
self.main_layout.addWidget(print_button)
ok_button = QtGui.QPushButton("Press to append One, Two and Three to class_variable list")
ok_button.clicked.connect(self.append_from_external_using_multi)
self.main_layout.addWidget(ok_button)
central_widget = QtGui.QWidget()
central_widget.setLayout(self.main_layout)
self.setCentralWidget(central_widget)
def setAttrbitute(self, arg):
print "Appending arg to class_variable: ", arg
self.class_variable.append(arg)
def append_from_external_using_multi(self):
# calling external function dirctly:
externalFunc(str(self.i))
# calling external function via pool.map_async:
pool = mp.Pool(processes=3)
pool.map_async( externalFunc, self.myList )
self.i+=1
def printVariable(self, arg):
print "\n\t self.class_variable = ", self.class_variable
if __name__ == '__main__':
manager = mp.Manager()
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.resize(480, 320)
window.show()
sys.exit(app.exec_())
它没有效果,因为默认情况下不同的进程不共享对象。通常,不能在进程之间共享任意Python对象 下面是一个小示例,说明了问题:
#!/usr/bin/env python
#XXX broken
import multiprocessing as mp
def f(a):
L.append(a)
if __name__=="__main__":
L = ['a']
pool = mp.Pool(1)
pool.map(f, 'b')
print(L) # -> ['a'] it hasn't changed in the parent
assert 'b' not in L
要修复此问题,您可以通过以下方式使用代理对象:
注意:由于非fork语义,您可能需要在Windows上将L显式传递给工作进程,例如:
def init(ll):
global L
L = ll
...
pool = mp.Pool(1, initializer=init, initargs=[L])
它没有效果,因为默认情况下不同的进程不共享对象。通常,不能在进程之间共享任意Python对象 下面是一个小示例,说明了问题:
#!/usr/bin/env python
#XXX broken
import multiprocessing as mp
def f(a):
L.append(a)
if __name__=="__main__":
L = ['a']
pool = mp.Pool(1)
pool.map(f, 'b')
print(L) # -> ['a'] it hasn't changed in the parent
assert 'b' not in L
要修复此问题,您可以通过以下方式使用代理对象:
注意:由于非fork语义,您可能需要在Windows上将L显式传递给工作进程,例如:
def init(ll):
global L
L = ll
...
pool = mp.Pool(1, initializer=init, initargs=[L])
谢谢你的解释!我已经调整了代码。它就像一个符咒!在原始问题下张贴了一个示例。再次感谢!谢谢你的解释!我已经调整了代码。它就像一个符咒!在原始问题下张贴了一个示例。再次感谢!