如何在Python中停止单个多处理过程?

时间:2014-06-05 18:12:03

标签: python qt pyqt multiprocessing pool

下面的代码创建了一个包含三个Progress Bars的对话窗口。每个进度条都链接到使用multiprocessing池启动的三个进程之一。

enter image description here

右键单击进度条时,会出现'停止进程' 菜单。该菜单链接到非功能stopProc()功能。目标是利用'停止流程()'用于停止右键单击过程的功能。如果你想展示如何完成这项任务,我将不胜感激:

enter image description here

from PyQt4 import QtGui, QtCore
import time
import multiprocessing as mp
poolPbDict=mp.Manager().dict()

def myFunct(inst):
    print 'myFunct():', inst.getName(), inst.getPbId(), '\n'
    for i in range(110):
        for n in range(150000): pass
        poolPbDict[ inst.getPbId() ]=i
    print '\n\t myFunct(): completed',inst.getName(),inst.getPbId(),poolPbDict[ inst.getPbId() ],'\n'


class PbWidget(QtGui.QProgressBar):
    def __init__(self, parent=None, total=20):
        super(PbWidget, self).__init__()
        self.setMinimum(1)
        self.setMaximum(105)        
        self._active = False
    def update_bar(self, argValue):
        self.setValue(argValue)
        QtGui.qApp.processEvents()
    def closeEvent(self, event):
        self._active = False

class ProgressBarTree(QtGui.QTreeWidget):  
    def __init__(self, parent=None):
        QtGui.QTreeWidget.__init__(self)
        self.items=[]
        self.pBars=[]
        self.setColumnCount(2)
        self.setHeaderLabels(['Name','Progress'])
        self.header().setStretchLastSection(True)

    def createJobItem(self, inst):
        item=QtGui.QTreeWidgetItem()
        item.setText(0, inst.getName())
        item.setData(1, QtCore.Qt.UserRole, inst)   
        self.addTopLevelItem(item)

        pb=PbWidget()
        self.setItemWidget(item, 1, pb)
        inst.setPbId(id(pb))

        self.items.append(item) 
        self.pBars.append(pb)           

        return inst

    def getpBars(self):
        return self.pBars 

class MyObject(object):
    def __init__(self, name):
        super(MyObject, self).__init__()
        self.name = name
        self.PbId = None
    def setPbId(self, arg):
        self.PbId=arg
    def getPbId(self):
        return self.PbId
    def getName(self):
        return self.name

class Window(QtGui.QWidget):
    def __init__(self):
        # declare instances
        self.instList=[]
        for each in ['One','Two','Three']:
            self.instList.append( MyObject(each) )

        QtGui.QWidget.__init__(self)
        layout = QtGui.QVBoxLayout(self)
        self.pbTree = ProgressBarTree()
        self.pbTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.pbTree.connect(self.pbTree,QtCore.SIGNAL('customContextMenuRequested(QPoint)'),self.showMenu)

        self.menu=QtGui.QMenu()
        menuItem1=self.menu.addAction('Stop Process')        
        self.connect(menuItem1,QtCore.SIGNAL('triggered()'),self.stopProc) 

        layout.addWidget(self.pbTree)
        # per instance create progress bar
        for inst in self.instList:
            inst=self.pbTree.createJobItem(inst)
        # button    
        button=QtGui.QPushButton("Run Processes")
        button.clicked.connect(self.runProcs)
        layout.addWidget(button)

    def showMenu(self, QPos):
        parentPosition=self.pbTree.mapToGlobal(QtCore.QPoint(0, 0))        
        menuPosition=parentPosition+QPos
        self.menu.move(menuPosition)
        self.menu.show() 

    def stopProc(self):
        print '\n\t stopProc()' 

    def setup(self, event):
        global unpaused
        unpaused = event

    def runProcs(self):
        self.resetBars()       
        self.event=mp.Event()
        self.pool=mp.Pool(2, self.setup, (self.event,))
        self.pool.map_async(myFunct, self.instList)
        self.event.set()     
        self.eventListener()
        poolPbDict.clear()

    def eventListener(self):
        global poolPbDict
        state=True
        while state:
            if not poolPbDict:
                time.sleep(0.2)
                continue
            self.updateBars()
            check=True
            if len(poolPbDict.keys())<len(self.instList):                
                check=False
            for value in poolPbDict.values():
                if value<105:
                    check=False
                    time.sleep(0.2)
                    break          
            if check:
                state=False
                print '\n\t eventListener() has been stopped \n'
                break  

    def updateBars(self):
        global poolPbDict
        pBars=self.pbTree.getpBars()
        for pb in pBars:
            pbId=id(pb)   
            value=poolPbDict.get(pbId)
            if value: 
                if value>=105: 
                    pb.update_bar(105)                                   
                else:
                    pb.update_bar(value)

    def resetBars(self):
        for pb in self.pbTree.getpBars():
            pb.reset()

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.resize(600,200)
    window.show()
    sys.exit(app.exec_())

1 个答案:

答案 0 :(得分:1)