多处理时如何获取每个进程ID

2024-05-14

我有一些问题,因为我是 Python 和 Pyside 的新手。

我有N个进程同时运行。

由于这些进程需要一些时间才能完成其工作,因此最终用户可能想要取消特定进程。因此,我需要一种方法来了解进程的 ID,以便将此功能添加到程序中。

有一个answer https://stackoverflow.com/a/15875187/3152155在 Stackoverflow 中,这正是我正在做的事情。

这是代码:

#!/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_())

我添加了一个“停止”按钮,并且我知道如何获取表中所选的行,但我不知道如何获取所选行的进程ID以终止。

update 1 :

为了让这更容易我可以改变

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

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

这样所有进程都必须等到进程完成

现在我们有一个进程正在运行,其他进程正在队列中,我如何才能获取该正在运行的进程的进程ID?


我编写了一个演示,或多或少地重现了多处理示例,并添加了中止上传的功能。它一次只能处理六个并行上传,因为这是 QNetworkAccessManager 允许的最大值。但是,可以通过简单地添加另一个 QNetworkAccessManager 来增加此限制。

我在测试演示时遇到一个问题。似乎在某些情况下,后数据可以发送两次(请参阅here http://lists.qt.nokia.com/public/qt-interest/2011-April/033132.html, 例如)。但我不知道这是否是 Qt 错误,或者我的测试设置的问题(我使用了 python 线程 httpserver)。不管怎样,通过关闭 uploadProgress 处理程序中的回复对象(见下文)就可以很容易地解决这个问题。

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_())
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多处理时如何获取每个进程ID 的相关文章

随机推荐

  • 如何删除或更改默认帮助命令?

    如何删除或至少更改discord py 中默认帮助命令的格式 我认为改变格式会很好 我根本不喜欢这种格式 尝试这个 bot remove command help 在导入之后将其放在代码的顶部 然后创建你自己的 或者要格式化它 请检查一下
  • 升级到最新支持库后Android JACK编译器错误

    Android Studio 2 2 3 Windows 10 64位 构建工具版本 25 Android Gradle插件版本2 2 3 升级到最新的支持库 从 23 4 0 到 25 1 0 并更改编译版本 从 23 到 25 后 我收
  • Groupby 应用自定义函数 Pandas

    我正在尝试在 pandas 中应用类似于 dplyr 中的 groupby 和 mutate 功能的自定义函数 我想做的是给出这样的 pandas 数据框 df pd DataFrame category1 a a a b b b cate
  • 表已满(使用 MEMORY 引擎)

    我想将生产数据库传输到我的开发机器上进行测试 它有 6 张桌子MEMORY出于性能目的的引擎 I did mysqldump routines hxxx uxxx pxxx prod database gt prod dump sql 当我
  • 在Python中根据for循环中的字典键创建动态变量

    我有这个程序 dict1 x 1 y 10 20 for each in list dict1 keys exec each dict1 each exec x dict x exec y dict y print x print y 我真
  • 寻找将集合映射到整数的双射函数

    对于任意两个序列 a b 其中 a a1 a2 an 且 b b1 b2 bn 0a b具有相同的元素 而不关心它们的顺序 例如 如果 a 1 1 2 3 b 2 1 3 1 c 3 2 1 3 则 f a f b f a f b 我知道有
  • 如何在 Tableau 中将数据规范化为某个范围

    在 Tableau 中 我尝试实现以下规范化逻辑 https stats stackexchange com questions 70801 how to normalize data to 0 1 range https stats st
  • MySQL 获取时间优化

    o我有一个包含 200 万个寄存器的表 但它很快就会增长得更多 基本上 该表包含具有相应描述符的图像的兴趣点 当我尝试执行选择在空间上靠近查询点的点的查询时 总执行时间花费太长 更准确地说 持续时间 获取 0 484 秒 27 441 秒
  • gnuplot:字体较小的字幕

    有人知道如何在 gnuplot 中插入较小字体的字幕吗 目前 我创建字幕的方式是使用 n在标题中 另外 我希望字幕的字体较小 提前致谢 这至少适用于 postscript 终端 出于某种原因x11不想缩放我的字体 也许这是一个错误 set
  • 枚举的子类化

    有没有一种简单的方法来子类化Javaenum 我问这个问题是因为我有大约 10 个实现相同接口的对象 但它们对某些方法也有相同的实现 因此我想通过将所有相同的实现放置在扩展的中间对象中来重用代码Enum它也是我需要的所有其他类的超类 或许事
  • 如何检测Windows版本是否合法? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我对获取版本信息不感兴趣 我想做的就是确保我的应用程序只能在合法版本的 Windows 上运行 而不是在盗版版本上运行 Windows 使
  • Django重复输入错误(1062)的原因?

    我更新了下面的信息以引用给我相同错误的不同模型 视图 它是一个更简单的模型 因此需要考虑的变量更少 我有以下模型 class Imaging order Order order description models ForeignKey I
  • Windows Phone SDK8 安装疑难解答

    我在运行 Windows 8 非专业版 的 PC 上使用 Visual Studio 2012 SDK 8 0 我决定购买另一个硬盘在同一台 PC 上安装 Windows Pro 以便在 PC 上运行 Windows Phone 模拟器 P
  • 在 TypeScript 中将 Chai 自定义插件声明为 NodeJS 全局变量

    这是我之前的问题 https stackoverflow com questions 61676032 declare nodejs global variables in before hook in webdriverio using
  • JSON 值的模式匹配

    运行 Postgres 12 5 的本地 docker 实例 4MBwork mem 我正在实施这个图案 https dba stackexchange com q 108447 3684搜索 json 中的任意字段 目标是搜索并返回 JS
  • 从 PHP 中的字符串中删除转义序列

    我正在使用一个已转义字符序列的 mysqldump 文件 我需要知道字符串的长度作为其数据库值 但转储中包含转义字符 这会增加字符串的长度 我用过stripslashes 它正确地取消转义单引号和双引号 但它不会触及 r n 我担心其中还有
  • Resharper 删除了 foreach 的产量。为什么?

    我最近了解到yield然后创建以下测试控制台程序 public static string Customers Paul Fred Doug Mark Josh public static string Admins Paul Doug M
  • 具有透明背景的 Swift 模态视图控制器 [重复]

    这个问题在这里已经有答案了 我知道这个话题很受欢迎 但我在编程语言中遇到了一些问题 事实是我仍然不明白我把代码放在哪里 好吧 我就来说说整个案子 我正在尝试制作一个与正常情况稍有不同的模态 Swift 通过单击按钮 ViewControll
  • 如何阻止与 RSpec 和 Capybara 的外部连接?

    在我的 Rails 项目中 我想编写非理想条件的测试 例如缺乏互联网连接或超时 例如 我正在使用 gem 来联系 API 并且希望确保在我的应用程序和外部 API 之间存在连接问题时能够正确处理错误 我已经可以通过用录像机制作固定装置并从
  • 多处理时如何获取每个进程ID

    我有一些问题 因为我是 Python 和 Pyside 的新手 我有N个进程同时运行 由于这些进程需要一些时间才能完成其工作 因此最终用户可能想要取消特定进程 因此 我需要一种方法来了解进程的 ID 以便将此功能添加到程序中 有一个answ