iT邦幫忙

0

在多層次QThread中readyreadstandardoutput無法正常輸出

  • 分享至 

  • xImage

當我使用Allocatrparalle控制同時間最大Task執行數量,Taskstart_output以及output並沒有訊息產生。而當我直接使用Task運行QProcess時,start_output以及output都會正常運作。

我有嘗試把output放在process_finished的開頭使用,雖然這樣的方式可以輸出訊息,但這樣的結果就會變成是我先執行完QProcess才把這些資訊一次釋放出來,就沒有達到即時顯示輸出的目的。

from PyQt5.QtCore import *
from PyQt5.QtWidgets import QApplication
from collections import deque
import threading
import time
import sys

class AllocateParalle(QThread):
    def __init__(self, queue_test):
        super().__init__()
        self.queue_test = queue_test
        self.activate = 0
        self.max_activate = 1
        self.time = 0
        self.lock = threading.Lock()
        self.list_thread = []

    def run(self):
        while len(self.queue_test)!=0:
            if self.activate < self.max_activate:
                with self.lock:
                    self.activate += 1
                    self.time += 1
                    cmd = self.queue_test.popleft()
                thread = Task(cmd, self.time)
                thread.finished.connect(self.finished_process)
                self.list_thread.append(thread)
                thread.start()
            else:
                time.sleep(3)

    def finished_process(self):
        with self.lock:
            self.activate-=1

class Task(QThread):
    def __init__(self, cmd, idx):
        super().__init__()
        self.lsf_task_process = None
        self.case_cmd = cmd
        self.idx = idx
        self.lock = threading.Lock()

    def run(self):
        self.lsf_task_process = QProcess()
        self.lsf_task_process.setProcessChannelMode(QProcess.MergedChannels)

        env = QProcessEnvironment.systemEnvironment()
        env.insert('PATH', '/usr/bin:'+env.value('PATH'))
        self.lsf_task_process.setProcessEnvironment(env)

        self.lsf_task_process.readyReadStandardOutput.connect(self.output)
        self.lsf_task_process.started.connect(self.start_output)
        self.lsf_task_process.finished.connect(lambda exitcode: self.process_finished(exitcode))

        self.lsf_task_process.start('bash', ['-c', self.case_cmd])
        self.lsf_task_process.waitForFinished(-1)

    def start_output(self):
        print('start remote')

    def output(self):
        while self.lsf_task_process.canReadLine():
            line_data = self.lsf_task_process.readLine().data().decode('utf-8', errors = 'replace').strip()
            print(f'[{self.idx}] {line_data}')

    def process_finished(self, exitcode):
        if exitcode!=0:
            print(f'[{self.idx}] error')
        else:
            print(f'[{self.idx}]success')

if __name__ =="__main__":
    app = QApplication(sys.argv)
    queue = deque()
    cmd = "for i in {1..5}; do echo 'Hello, world!'; sleep 1; done"
    for i in range(3):
        queue.appendleft(cmd)
    thread = AllocateParalle(queue)
    # thread = Task(cmd, 0)
    thread.start()
    sys.exit(app.exec())
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友回答

立即登入回答