How to get each Process ID when multiprocessing
Question: I have some problems because I'm newbie in Python and Pyside.

I have N processes which are running at the same time.

Since these processes take some times to finish their job, it's possible that
end user wants to cancel a specific process. So I need a way to know the IDs
of processes for adding this feature to the program.

There is an [answer](http://stackoverflow.com/a/15875187/3152155) in
Stackoverflow which is exactly what I'm doing.

Here is the code :

    
    
    #!/usr/bin/env python3
    import multiprocessing, multiprocessing.pool, time, random, sys
    from PySide.QtCore import *
    from PySide.QtGui import *
    
    def compute(num_row):
        print("worker started at %d" % num_row)
        random_number = random.randint(1, 10)
        for second in range(random_number):
            progress = float(second) / float(random_number) * 100
            compute.queue.put((num_row, progress,))
            time.sleep(1)
        compute.queue.put((num_row, 100))
    
    def pool_init(queue):
        # see http://stackoverflow.com/a/3843313/852994
        compute.queue = queue
    
    class MainWindow(QMainWindow):
        def __init__(self):
            QMainWindow.__init__(self)
            self.toolBar = self.addToolBar("Toolbar")
            self.toolBar.addAction(QAction('Add Task', self, triggered=self.addTask))
            self.table = QTableWidget()
            self.table.verticalHeader().hide()
            self.table.setColumnCount(2)
            self.setCentralWidget(self.table)
    
            # Pool of Background Processes
            self.queue = multiprocessing.Queue()
            self.pool = multiprocessing.Pool(processes=4, initializer=pool_init, initargs=(self.queue,))
            # Check for progress periodically
            self.timer = QTimer()
            self.timer.timeout.connect(self.updateProgress)
            self.timer.start(2000)
    
        def addTask(self):
            num_row = self.table.rowCount()
            self.pool.apply_async(func=compute, args=(num_row,))
            label = QLabel("Queued")
            bar = QProgressBar()
            bar.setValue(0)
            self.table.setRowCount(num_row + 1)
            self.table.setCellWidget(num_row, 0, label)
            self.table.setCellWidget(num_row, 1, bar)
    
        def updateProgress(self):
            if self.queue.empty(): return
            num_row, progress = self.queue.get() # unpack
            print("received progress of %s at %s" % (progress, num_row))
            label = self.table.cellWidget(num_row, 0)
            bar = self.table.cellWidget(num_row, 1)
            bar.setValue(progress)
            if progress == 100:
                label.setText('Finished')
            elif label.text() == 'Queued':
                label.setText('Downloading')
            self.updateProgress() # recursion
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        main_window = MainWindow()
        main_window.show()
        sys.exit(app.exec_())
    

I added an "stop" button, and I know how to get the selected row in the table,
but I don't know how to get the process id of the selected row for
terminating.

**update 1** :

for make this easier I can change

`multiprocessing.Pool(processes=4, initializer=pool_init,
initargs=(self.queue,))` to

    
    
    multiprocessing.Pool(processes=1, initializer=pool_init, initargs=(self.queue,))
    

in this way all processes have to wait till a process finish

now we have one process running and others are in queue,How I can get just the
process id of that running process ?


Answer: I hacked together an demo that more or less reproduces the multiprocessing
example, with the addition of the ability to abort uploads. It can only handle
six parallel uploads at a time because that is the maximum
QNetworkAccessManager will allow. However, this limit could be increased by
simply adding another QNetworkAccessManager.

There was one issue I came across while testing the demo. It seems that under
some circumstances, the post-data can get sent twice (see
[here](http://lists.qt.nokia.com/public/qt-interest/2011-April/033132.html),
for example). But I don't know whether this is a Qt bug, or an issue with my
test setup (I used a python threaded httpserver). Anyway, it was easy enough
to fix by closing the reply-object in the uploadProgress handler (see below).

    
    
    from PyQt4 import QtCore, QtGui, QtNetwork
    
    class Window(QtGui.QWidget):
        def __init__(self, address):
            QtGui.QWidget.__init__(self)
            self.address = address
            self.table = QtGui.QTableWidget(self)
            header = self.table.horizontalHeader()
            header.setStretchLastSection(True)
            header.hide()
            self.table.setColumnCount(2)
            self.button = QtGui.QPushButton('Add Upload', self)
            self.button.clicked.connect(self.handleAddUpload)
            layout = QtGui.QVBoxLayout(self)
            layout.addWidget(self.table)
            layout.addWidget(self.button)
            self.netaccess = QtNetwork.QNetworkAccessManager(self)
            self._uploaders = {}
    
        def handleAddUpload(self):
            stream = QtCore.QFile('files/sample.tar.bz2')
            if stream.open(QtCore.QIODevice.ReadOnly):
                data = stream.readAll()
                stream.close()
                row = self.table.rowCount()
                button = QtGui.QPushButton('Abort', self.table)
                button.clicked.connect(lambda: self.handleAbort(row))
                progress = QtGui.QProgressBar(self.table)
                progress.setRange(0, len(data))
                self.table.setRowCount(row + 1)
                self.table.setCellWidget(row, 0, button)
                self.table.setCellWidget(row, 1, progress)
                uploader = self._uploaders[row] = Uploader(row, self.netaccess)
                uploader.uploadProgress.connect(self.handleUploadProgress)
                uploader.uploadFinished.connect(self.handleUploadFinished)
                uploader.upload(data, self.address)
    
        def handleUploadProgress(self, key, sent, total):
            print('upload(%d): %d [%d]' % (key, sent, total))
            progress = self.table.cellWidget(key, 1)
            progress.setValue(sent)
    
        def handleUploadFinished(self, key):
            print('upload(%d) finished' % key)
            button = self.table.cellWidget(key, 0)
            button.setDisabled(True)
            uploader = self._uploaders.pop(key)
            uploader.deleteLater()
    
        def handleAbort(self, key):
            try:
                self._uploaders[key].abort()
            except (KeyError, AttributeError):
                pass
    
    class Uploader(QtCore.QObject):
        uploadProgress = QtCore.pyqtSignal(object, int, int)
        uploadFinished = QtCore.pyqtSignal(object)
    
        def __init__(self, key, parent):
            QtCore.QObject.__init__(self, parent)
            self._key = key
            self._reply = None
    
        def abort(self):
            if self._reply is not None:
                self._reply.abort()
    
        def upload(self, data, url):
            if self._reply is None:
                request = QtNetwork.QNetworkRequest(QtCore.QUrl(url))
                request.setHeader(
                    QtNetwork.QNetworkRequest.ContentTypeHeader,
                    'application/x-www-form-urlencoded')
                self._reply = self.parent().post(request, data)
                self._reply.uploadProgress.connect(self.handleUploadProgress)
                self._reply.finished.connect(self.handleFinished)
    
        def handleUploadProgress(self, sent, total):
            self.uploadProgress.emit(self._key, sent, total)
            if sent >= total:
                # prevent duplicated uploads
                self._reply.close()
    
        def handleFinished(self):
            self._reply.deleteLater()
            self._reply = None
            self.uploadFinished.emit(self._key)
    
    if __name__ == '__main__':
    
        import sys
        app = QtGui.QApplication(sys.argv)
        window = Window('http://localhost:54321/upload')
        window.setGeometry(500, 300, 500, 300)
        window.show()
        sys.exit(app.exec_())
    

