2018-12-20

Flaskを利用した並列処理をThreadを利用する際の忘備録

# スレッド(thread)とは

> プログラムの処理の実行単位
引用:スレッド (thread)とは

# スレッドを複数利用するタイミング


・並列処理を行う必要がある場合

# Pythonで複数Threadを利用する場合



  • Celery
    • ジョブキューを使う
    • redisなど使うため準備が少し必要
  • Thread

import time
import threading

def func1():
    while True:
        print("func1")
        time.sleep(1)


def func2():
    while True:
        print("func2")
        time.sleep(1)


if __name__ == "__main__":
    thread_1 = threading.Thread(target=func1)
    thread_2 = threading.Thread(target=func2)

    thread_1.start()
    thread_2.start()

引用:Pythonの並列・並行処理サンプルコードまとめ


# Flaskで利用する場合



from datetime import datetime
from flask import Flask, make_response
from time import sleep
import threading

app = Flask(__name__)

class MyThread(threading.Thread):
    def __init__(self):
        super(MyThread, self).__init__()
        self.stop_event = threading.Event()

    def stop(self):
        self.stop_event.set()

    def run(self):
        try:
            for _ in range(1000):
                print(f'{datetime.now():%H:%M:%S}')
                sleep(1)

                # 定期的にフラグを確認して停止させる
                if self.stop_event.is_set():
                    break
        finally:
            print('時間のかかる処理が終わりました\n')

jobs = {}

@app.route('/start/<id>/')
def root(id):
    t = MyThread()
    t.start()
    jobs[id] = t
    return make_response(f'{id}の処理を受け付けました\n'), 202

@app.route('/stop/<id>/')
def stop(id):
    jobs[id].stop()
    del jobs[id]
    return make_response(f'{id}の中止処理を受け付けました\n'), 202

@app.route('/status/<id>/')
def status(id):
    if id in jobs:
        return make_response(f'{id}は実行中です\n'), 200
    else:
        return make_response(f'{id}は実行していません\n'), 200


引用:PythonでThreadを使うflaskサンプルを作ってみた

# 並列処理の注意点



  • Flaskのデフォルトでは複数のリクエストを同時に処理することができません。
  • 並列処理を有効にして同時アクセスを可能にするにはthreaded=Trueパラメータを設定します。


引用) Flaskのデフォルトでは同時アクセスを処理できない





注目の投稿

 PythonのTweepyを利用して、Twitter APIを利用している。 その中で、ハマったポイントをメモしておく。 まず、Searchに関して。 Twitter検索は、クライアントアプリ側では、全期間の検索が可能になっている。 一方で、APIを利用する際は、過去1週間しか...