2017-08-09 4 views
4

私は無限の時間の間、毎秒7つのデバイスからデータを読み取るコードを持っています。各ループは、7つのプロセスを開始するスレッドが作成されます。各プロセスが完了すると、プログラムは1秒間待ってから再開します。コードスニペットは次のとおりです。Python:スレッド/マルチプロセッシングがCPUを100%使用しないようにするにはどうすればよいですか?

def all_thread(): #function that handels the threading 
    thread = threading.Thread(target=all_process) #prepares a thread for the devices 
    thread.start() #starts a thread for the devices 

def all_process(): #function that prepares and runs processes 
    processes = [] #empty list for the processes to be stored 
    while len(gas_list) > 0: #this gaslist holds the connection information for my devices 
     for sen in gas_list: #for each sen(sensor) in the gas list 
      proc = multiprocessing.Process(target=main_reader, args=(sen, q)) #declaring a process variable that sends the gas object, value and queue information to reading function 
      processes.append(proc) #adding the process to the processes list 
      proc.start() #start the process 
     for sen in processes: #for each sensor in the processes list 
      sen.join() #wait for all the processes to complete before starting again 
     time.sleep(1) #wait one second 

ただし、これは私のCPUの100%を使用しています。これは、スレッディングとマルチプロセッシングの設計によるものか、あるいは悪いコーディングによるものなのでしょうか? CPU使用量を制限できる方法はありますか?ありがとう!

アップデート:私は質問にそれを置くよう

コメントはmain_reader()機能を言及しました。すべてのデータは各デバイスで読み取られ、すべてのデータが取り込まれ、リストに追加されます。リストはキューに入れられ、tkinter GUIに表示されます。あなたがコメントで状態として

def main_reader(data, q): #this function reads the device which takes less than a second 
    output_list = get_registry(data) #this function takes the device information, reads the registry and returns a list of data 
    q.put(output_list) #put the output list into the queue 
+0

Pythonでプロセスを開始するとは、Pythonインタプリタの新しいインスタンスを起動することです。つまり、4〜8個のコアで動作する別々のインタプリタが7つあります。新しいインタプリタが生成されると、それは親プロセスからリソースの束を継承し、それを実行できるようになります。つまり、新しいプロセスを生成することはかなり遅くて高価になる可能性があります。あなたのプロセスは 'main_reader()'という名前の関数を実行しています。あなたがやっている作業は主にIOのものです。これらのプロセスの代わりにデーモンの束を起動しようとしましたか? – orangeInk

+0

@ orangeInk yaすべてのIOです。 'main_reader()'はデバイスを読み込み、表示するデータを準備します。私はデーモンと全く遊んでいない。今は、マルチプロセッシングを使用して、デバイスが動作している間にtkinter GUIがフリーズしないようにしています。デーモンもこれを達成できますか? – GreenSaber

+0

これからmain_readerで何が起こるかを見ることは不可能です。それがあなたの処理が起こる場所です。 All_processはjoin()で待機します。あなたのwhileループの最初の行として 'processes = []'を動かしたいと思うかもしれません。現在結合されているプロセスがそのプロセスから削除されないので、リストは増加し続けます。反復後に反復を追加するだけです。 – Hannu

答えて

2

、あなたのmain_readerは、プロセス作成オーバーヘッドがあなたの問題を引き起こす可能性を意味し、実行するのはほんの一瞬を取ります。

multiprocessing.Poolの例を示します。これにより、作業者のプールが作成され、タスクがタスクに送信されます。プロセスは一度だけ起動され、無限ループである場合はシャットダウンまたは結合されません。プールをシャットダウンしたい場合は、プールに参加したり閉じたりすることで行うことができます(そのドキュメントを参照)。

from multiprocessing import Pool, Manager 
from time import sleep 
import threading 
from random import random 

gas_list = [1,2,3,4,5,6,7,8,9,10] 

def main_reader(sen, rqu): 
    output = "%d/%f" % (sen, random()) 
    rqu.put(output) 


def all_processes(rq): 
    p = Pool(len(gas_list) + 1) 
    while True: 
     for sen in gas_list: 
      p.apply_async(main_reader, args=(sen, rq)) 

     sleep(1) 

m = Manager() 
q = m.Queue() 
t = threading.Thread(target=all_processes, args=(q,)) 
t.daemon = True 
t.start() 

while True: 
    r = q.get() 
    print r 

これが解決しない場合は、さらに深く掘り下げてください。私はまず、あなたの無限ループの中で睡眠を10秒以上に増やします。これにより、プログラムの動作を監視することができます。 CPUがしばらくピークを迎えてから10秒ほど落ち着くと、main_readerに問題があることがわかります。まだ100%であれば、あなたの問題は他の場所になければなりません。

プログラムのこの部分に問題がない可能性はありますか?あなたはメインプログラムが何か他のことをしていることを示す、スレッド内でこれをすべて起動するようです。 CPUをピークにする何か他のものにすることはできますか?

+0

私は今これを試してみるつもりです。私はあなたに戻ってきます。私は、Tkinterのメインループとデバイスで行う必要のある作業を分離するためのスレッドを立ち上げます。 – GreenSaber

+0

その後、tkinterループなしで試すことができます。あなたのプログラムのこの部分を起動した直後に、それを起動して寝る(ビッグタイム)。あなたのアプリケーションはそれほど多くはありませんが、これらのすべてのバックグラウンドタスクを実行しているにもかかわらずうまく動作する場合は、コードのこの部分に問題がないことを少なくとも知っています。 – Hannu

+0

私は仕事をしようとしているプールを見ることができますが、 'main_reader()'には何も行きません。 – GreenSaber

関連する問題