如何在Python中停止单个多进程?
下面的代码会创建一个对话窗口,里面有三个进度条。每个进度条都和三个不同的进程相连,这些进程都是通过 multiprocessing
的 Pool 来启动的。
当你右键点击进度条时,会弹出一个 '停止进程' 的菜单。这个菜单是和一个没有实际功能的 stopProc()
函数相连的。我们的目标是利用 '停止进程()' 函数来停止被右键点击的进程。如果你能告诉我怎么做到这一点,我会非常感激:
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 个回答
2
用 myproc.terminate()
来结束一个进程 -- https://docs.python.org/2/library/multiprocessing.html#multiprocessing.Process.terminate