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 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 https://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 ?
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, 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).
The easiest way is to list all of the processes and then use os.kill to kill it.
But you should look at doing this with threading.