當我使用Allocatrparalle
控制同時間最大Task
執行數量,Task
的start_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())