読者です 読者をやめる 読者になる 読者になる

上限数を決めて協調しないスレッドを動かす

協調しないで並行作業を行うスレッドを使いたくなったのでちょっとテスト。協調しない並行作業ってのはスレッドが起動したときに割り当てられた仕事を「他のスレッドの状態にまったく依存せずに」行う作業のこと(勝手に定義したよ)。各スレッドは決められた範囲をダウンロードする分割ダウンロードみたいなイメージかな*1
マルチコアのマシンを使ってそれなりに量の多い作業をするときはできるだけスレッドを使うようにしたい。協調しないでいいときは割とシンプルに書ける。

import threading
import time
import random

lock = threading.Lock()
output = []

def count(key):
  # 0.01〜0.1秒待機してからoutputに自分の担当する数字を格納する
  time.sleep(random.random()/10)
  lock.acquire()
  output.append(key)
  lock.release()

def main():
  thread_pool = []
  thread_num = 10 # 最大スレッド数

  for i in range(100):
    while len(thread_pool) >= thread_num:
      thread_pool = [th for th in thread_pool if th.isAlive()]
      time.sleep(0.01)
    th = threading.Thread(target=count, args=(i,))
    thread_pool.append(th)
    th.setDaemon(True)
    th.start()

  # 全部のスレッドが終了するまで待機
  while len(thread_pool) > 0:
    thread_pool = [th for th in thread_pool if th.isAlive()]
    time.sleep(0.01)

  print output

if __name__ == '__main__':
  main()

出力

[2, 9, 5, 4, 11, 12, 7, 0, 1, 3, 8, 15, 6, 13, 10, 16, 17, 22, 14, 19, 18, 20, 23, 21, 26, 29, 24, 25, 28, 36, 37, 32, 27, 30, 33, 35, 31, 34, 43, 45, 40, 41, 3
8, 42, 39, 47, 52, 51, 49, 48, 46, 54, 44, 50, 53, 55, 62, 61, 65, 56, 64, 59, 66, 60, 63, 58, 69, 57, 70, 68, 77, 67, 75, 72, 73, 76, 71, 83, 79, 87, 86, 81, 7
8, 74, 80, 88, 94, 82, 84, 85, 89, 92, 98, 91, 95, 90, 93, 97, 99, 96]

*1:一つのファイルを協調して落としてるからちょっと違うか。まあいいや。