QRunnable在多个核心

时间:2016-10-12 18:15:25

标签: multithreading python-3.x pyqt5

我正在学习QRunnable,我有以下代码:

from PyQt5.QtCore import QThreadPool, QRunnable

class SomeObjectToDoComplicatedStuff(QRunnable):
    def __init__(self, name):
        QRunnable.__init__(self)
        self.name = name

    def run(self):
        print('running', self.name)
        a = 10
        b = 30
        c = 0
        for i in range(5000000):
            c += a**b
        print('done', self.name)


pool = QThreadPool.globalInstance()
pool.setMaxThreadCount(10)

batch_size = 100

workers = [None] * batch_size

for i in range(batch_size):
    worker = SomeObjectToDoComplicatedStuff('object ' + str(i))
    workers[i] = worker
    pool.start(worker)

print('All cued')
pool.waitForDone()

# processing the results back
for i in range(batch_size):
    print(workers[i].name, ' - examining again.')

我看到确实有不同的流程被交替,但都发生在一个核心上。

如何使用所有处理器内核运行此代码?

PS:这段代码只是我正在制作的超复杂数字运算应用程序的简化。在其中,我想在几个线程中执行蒙特卡罗,而工作者本身是一个复杂的优化问题。 我已经尝试过python多处理模块,但它并没有很好地处理scipy。

2 个答案:

答案 0 :(得分:1)

不确定这将有多大用处,但您的示例脚本的多处理版本将是这样的:

from multiprocessing import Pool

class Worker(object):
    def __init__(self, name):
        self.name = name

    def run(self):
        print('running', self.name)
        a = 10
        b = 30
        c = 0
        for i in range(5000000):
            c += a**b
        print('done', self.name)
        return self.name, c

def caller(worker):
    return worker.run()

def run():
    pool = Pool()
    batch_size = 10
    workers = (Worker('object%d' % i) for i in range(batch_size))
    result = pool.map(caller, workers)
    for item in result:
        print('%s = %s' % item)

if __name__ == '__main__':

    run()

答案 1 :(得分:0)

  

如何使用所有处理器内核运行此代码?

使用PyQt(QRunner / QThread和可能),我认为这几乎是不可能的,因为它们(python版本,而不是C ++)正在使用GIL。

最简单的解决方案是使用multiprocessing,但由于你在scipy中使用它时遇到一些问题,你应该寻找一些非标准库。

我建议你看一下ipyparallel,AFAIK,它们是在同一个保护伞下开发的,所以它们很可能无缝地工作。