2016-12-22 15 views
0

私は以下のコードについて簡単な問題や質問があります。whileループ内の複数のスレッド

ip = '192.168.0.' 
count = 0 
while count <= 255: 
    print(count) 
    count += 1 
    for i in range(10): 
     ipg=ip+str(count) 
     t = Thread(target=conn, args=(ipg,80)) 
     t.start() 

は、私は10個のスレッドを毎回実行し、それが終了するのを待ってから、カウントまで次の10個のスレッドを続行したい< = 255

私は私の問題を理解し、なぜそれがために10個のスレッドを実行しませんすべてのカウントが増加しますが、それを解決する方法ではなく、どんな助けも高く評価されます。

+0

私はキューを追加するべきだと思います –

+0

'ThreadPool(processes = 10)で' multiprocessing.pool'の大部分の文書化されていない['ThreadPool'](http://stackoverflow.com/a/3386632/355230) ) '。 'while(使用中ではありません(結果の中でa_threadのためにすべて(a_thread.ready()を使用することができます)):pass'を実行して、各スレッドが10回すべてアイドル状態になるのを待ちます。他の質問に[私の答え](http://stackoverflow.com/a/18283388/355230)を参照してください。 – martineau

+0

あなたの答えをありがとう、現時点で私はキューリストで作業していますが、私はプールの利点は、10の1つのプロセスが完了した後、10のすべてが完了する前に待機するのではなく、右 ? –

答えて

0

それは簡単concurrents.futuresライブラリ

ここでは例のコードだ使用して達成することができます:ここ

from concurrent.futures import ThreadPoolExecutor 

ip = '192.168.0.' 
count = 0 

THREAD_COUNT = 10 

def work_done(future): 
    result = future.result() 
    # work with your result here 


def main(): 
    with ThreadPoolExecutor(THREAD_COUNT) as executor: 
     while count <= 255: 
      count += 1 
      ipg=ip+str(count) 
      executor.submit(conn, ipg, 80).add_done_callback(work_done) 

if __name__ == '__main__': 
    main() 

をexecutorは、それが提出するすべてのタスクに対して未来を返します。 add_done_callback()スレッドからの完了タスクを使用してメインスレッド(メインスレッドをブロックする)に戻った場合、真の並列処理が本当に必要な場合は、将来のオブジェクトを別々に待つ必要があることに留意してください。そのためのコードスニペットがあります。

from concurrent.futures import ThreadPoolExecutor 
from concurrent.futures._base import wait 

futures = [] 
with ThreadPoolExecutor(THREAD_COUNT) as executor: 
    while count <= 255: 
     count += 1 
     ipg=ip+str(count) 
     futures.append(executor.submit(conn, ipg, 80)) 
wait(futures) 

for succeded, failed in futures: 
    # work with your result here 

これが役に立ちます。

+0

ここでは、ThreadPoolExecutorが最良の方法に従うため、この回答を優先しています。他の答えも正しい場所。みんな、ありがとう ! –

0

実行可能なオプションは、multiprocessingThreadPoolとして@martineauが推奨され、queueを使用します。次に、10個の異なるスレッドで同時に要求を実行するqueueの例を示します。できるだけ早くスレッドは、それが他の労働者の状態を気にすることなく次のタスクをピックアップ完了すると、それはバッチ処理のいずれかの種類をしないことに注意してください:

import queue 
import threading 

def conn(): 
    try: 
     while True: 
      ip, port = que.get_nowait() 
      print('Connecting to {}:{}'.format(ip, port)) 
      que.task_done() 
    except queue.Empty: 
     pass 

que = queue.Queue() 
for i in range(256): 
    que.put(('192.168.0.' + str(i), 80)) 

# Start workers 
threads = [threading.Thread(target=conn) for _ in range(10)] 
for t in threads: 
    t.start() 

# Wait que to empty 
que.join() 

# Wait workers to die 
for t in threads: 
    t.join() 

出力:

Connecting to 192.168.0.0:80 
Connecting to 192.168.0.1:80 
Connecting to 192.168.0.2:80 
Connecting to 192.168.0.3:80 
Connecting to 192.168.0.4:80 
Connecting to 192.168.0.5:80 
Connecting to 192.168.0.6:80 
Connecting to 192.168.0.7:80 
Connecting to 192.168.0.8:80 
Connecting to 192.168.0.9:80 
Connecting to 192.168.0.10:80 
Connecting to 192.168.0.11:80 
... 
0

私はあなたを修正しましたそれが正しいロジックを持っているように、あなたが望むことをするために、私はそれを実行していないことに注意していますが、一般的なアイデアを得るいただければ幸いしてください:

import time 
from threading import Thread 

ip = '192.168.0.' 
count = 0 
while count <= 255: 
    print(count) 
    # a list to keep your threads while they're running 
    alist = [] 
    for i in range(10): 
     # count must be increased here to count threads to 255 
     count += 1 
     ipg=ip+str(count) 
     t = Thread(target=conn, args=(ipg,80)) 
     t.start() 
     alist.append(t) 

    # check if threads are still running 
    while len(alist) > 0: 
     time.sleep(0.01) 
     for t in alist: 
      if not t.isAlive(): 
       # remove completed threads 
       alist.remove(t) 
関連する問題