Python:多处理解除行为

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

有一个class属性self.class\u变量。单击“按”将一个、两个和三个附加到class_变量列表按钮,将调用一个外部到MainWindow类externalFunc函数,该函数用于附加“一”、“二”、“三”。一行:

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])

谢谢你的解释!我已经调整了代码。它就像一个符咒!在原始问题下张贴了一个示例。再次感谢!谢谢你的解释!我已经调整了代码。它就像一个符咒!在原始问题下张贴了一个示例。再次感谢!