項目中碰到了這樣的一個問題苛坚,我的意圖是實現(xiàn)pyside2中的進(jìn)度條實時跟進(jìn)項目進(jìn)度擦盾,為了防止主進(jìn)程也就是程序主窗口陷入阻塞狀態(tài),我需要額外再開一個線程出來并行處理問題:
#首先需要定義一個自定義線程類
# 循環(huán)監(jiān)視多進(jìn)程數(shù)目
def cycleMonitorThread(self):
self.ongoing = True
qlist = []
# 使用無限循環(huán),不間斷的獲取隊列長度姨丈,以此更新進(jìn)度條進(jìn)度
while True:
# 獲取隊列內(nèi)數(shù)據(jù)的長度,不取出擅腰,就看長度
qlist.append(self.qcount.get())
print(qlist)
so.process_update.emit(len(qlist))
# 隊列的長度是絕對不會超過文件數(shù)量的蟋恬,所以一旦隊列長度等于了文件長度,就退出無限循環(huán)
if len(qlist) == self.progressNum:
self.ui.transformbtn.setText("轉(zhuǎn)換完成")
self.ui.transformbtn.setEnabled(True)
self.ongoing = False
break
# 再在程序合適的地方插入執(zhí)行線程的語句
thread1 = threading.Thread(target=self.cycleMonitorThread)
thread1.start()
我原本以為在子進(jìn)程中只需要使用q = queue.Queue()
就可以在主進(jìn)程和子進(jìn)程中進(jìn)行通信溝通趁冈。
以下插入項目的簡化代碼(我測試摸索問題在哪用的就是這個):
from queue import Queue
from threading import Thread
def foo(q):
q.put('hello')
return q.get()
def run(q):
p = mp.Pool()
p.apply_async(func=foo, args=(q,))
p.close()
p.join()
if __name__ == '__main__':
q = Queue()
thread = Thread(target=run, args=(q,))
thread.start()
print(q.get())
可是情況并沒有我想象的那么簡單歼争,各位可以復(fù)制以上代碼去運行,你們會發(fā)現(xiàn)q.get()
并不會返回任何數(shù)據(jù)過來
經(jīng)過好幾天的思考渗勘,并結(jié)合多方查詢后明白了沐绒,在多進(jìn)程中,queue一般適用于子進(jìn)程間的通信旺坠,不能用于父子進(jìn)程中的通信乔遮。那么我實在是想實現(xiàn)父子之間的通信該怎么辦呢?
解決方法:
在父進(jìn)程中使用multiprocessing.Manage()
中的Queue()
方法取刃,然后將此對象實例化蹋肮,我這里用q
表示出刷,并將q
作為參數(shù)傳進(jìn)進(jìn)程方法中。具體代碼如下:
import multiprocessing
from threading import Thread
def foo(q):
q.put('hello')
def run(q):
p = multiprocessing.Pool()
p.apply_async(func=foo, args=(q,))
p.close()
p.join()
if __name__ == '__main__':
mg = multiprocessing.Manager()
q = mg.Queue()
thread = Thread(target=run, args=(q,))
thread.start()
print(q.get())
這次運行之后就能輸出hello
了坯辩。
曉得了這個思路之后馁龟,剩下的就是將其帶入項目中進(jìn)行實現(xiàn)。最終我實現(xiàn)了進(jìn)度條實時根據(jù)項目進(jìn)度更新的目的漆魔。