2016-10-12 8 views
0

QRunnable私は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.') 

を私はすべて1つのコア上で起こっている確かに交互にされている別のプロセスがあることがわかり、しかし。

すべてのプロセッサコアを使用してこのコードを実行するにはどうすればよいですか?

PS:このコードは、私が作っている超複雑な数のクランチアプリケーションの単なる単純化です。その中で、私はいくつかのスレッドでMonte Carloをやりたいと思っています。そして、ワーカー自体は複雑な最適化問題です。 私はPythonマルチプロセッシングモジュールを試しましたが、scipyをあまりうまく扱えません。

+0

[GIL](http://wiki.python.org/moin/GlobalInterpreterLock )。 – ekhumoro

+0

私はGILを完全に認識していますが、問題はまだ複数のコアで実行する方法です。 –

+0

それは言い換えれば、違反行為のようです。関連するコードがGILをリリースしない場合、あなたの質問のコードを何か別のものにすることは不可能です。マルチプロセッシングモジュールは、この問題のために正確に存在します。ですから、それを使用できない場合は、GILなしでコードを実行できる拡張機能を作成する必要があります。参照:[PythonのGILとCythonの克服](http://lbolla.info/blog/2013/12/23/python-threads-cython-gil) – ekhumoro

答えて

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() 
+0

このように見えますが、Windowsではクラッシュしますが、後でlinuxで試してみます。 –

+0

@SantiPeñate-Vera私はサンプルコードを修正しました。 Windowsは* fork *を持っていないので、無限回帰を避けるためにスクリプトのエントリーポイントを守る必要があります。 – ekhumoro

+0

生産コードをLinux上で試してみました。 –

0

すべてのプロセッサコアを使用してこのコードを実行するにはどうすればよいですか?

PyQt(QRunner/QThreadなど)を使用しているので、Pythonバージョン(C++ではなく)がGILを使用しているためほとんど不可能です。

最も簡単な解決策はmultiprocessingですが、scipyに沿って使用する際に問題があるので、標準ではないライブラリを探すべきです。

ipyparallel AFAIKは同じ傘の下で開発されているため、シームレスに動作する可能性があります。

関連する問題