目前我正在尝试在一个线程内启动一个池,在这个池中我将创建Qt的QWebEnginePage的实例。
有两件事正在发生,而这些事情似乎正在发生。
第一:
它通过列表进行迭代的方式并不准确(要么跳过某些条目,要么它没有排序(不确定它是如何排序的) ))第二
循环挂起,意味着一切都停止了,似乎我无能为力。
from multiprocessing.pool import Pool
from multiprocessing import Process
from threading import Thread
from PyQt5.Qt import *
class Webkit(QWebEnginePage):
def __init__(self):
self.app = QApplication([])
super(Webkit, self).__init__()
self.loadFinished.connect(self.pageFinishedLoading)
def loadUrl(self, url):
self.load(QUrl(url))
self.app.exec()
def pageFinishedLoading(self):
self.app.quit()
def first():
"""Thread + Process"""
#Thread(target=lambda: Process(target=second().foo()).start(), daemon=False).start()
"""Thread"""
Thread(target=second().foo()).start()
"""Process"""
#Process(target=second().foo()).start()
class second:
def foo(self):
count = 10
print("Starting pool")
with Pool(1) as pool:
pool.map(final, range(count))
print("Starting process")
for x in range(count):
p = Process(target=final, args=(x, ))
p.start()
p.join()
print("Finished")
def final(a):
print("Now creating webkit", a)
wk = Webkit()
wk.loadUrl("https://google.com")
if __name__ == '__main__':
app = QApplication([])
first()
app.exec()
输出:
Starting pool
Now creating webkit 0
Now creating webkit 1
Now creating webkit 3
Now creating webkit 4
Now creating webkit 6
Now creating webkit 7
Now creating webkit 9
预期产出:
Starting pool
Now creating webkit 0
Now creating webkit 1
Now creating webkit 2
Now creating webkit 3
Now creating webkit 4
Now creating webkit 5
Now creating webkit 6
Now creating webkit 7
Now creating webkit 8
Now creating webkit 9
Starting process
Now creating webkit 0
Now creating webkit 1
Now creating webkit 2
Now creating webkit 3
Now creating webkit 4
Now creating webkit 5
Now creating webkit 6
Now creating webkit 7
Now creating webkit 8
Now creating webkit 9
Finished
编辑:for循环使其成为破坏的游泳池
答案 0 :(得分:0)
我无法弄清楚任何真正的解决方案,所以我为它做了一个黑客,它并不漂亮,但它的工作几乎和普通的游泳池一样。它为每个进程创建了一个额外的进程,这意味着它将使用额外的内存,但除此之外它应该没问题。
如果有人有更好的解决方案,请发布:)
import multiprocessing as mp
from multiprocessing.pool import Pool, starmapstar
import itertools
def caller(func, *args):
try: length = len(*args)
except TypeError: length = 1
p = mp.Process(target=func, args=tuple(*args) if length > 1 else (*args, ))
p.start()
return p.join() # This will only return None
class NoDaemonProcess(mp.Process):
# make 'daemon' attribute always return False
def _get_daemon(self):
return False
def _set_daemon(self, value):
pass
daemon = property(_get_daemon, _set_daemon)
class MyPool(Pool):
Process = NoDaemonProcess
def _map_async(self, func, iterable, mapper, chunksize=None, callback=None, error_callback=None):
iterable = zip(itertools.repeat(func), iterable)
mapper = starmapstar
func = caller
return super(MyPool, self)._map_async(func, iterable, mapper, chunksize, callback, error_callback)