マルチスレッドでinputを取得し、任意のタイミングで入力用のスレッドを削除する

執筆:  “K.S”

はじめに

初めまして。プログラマーのK.Sです。

今回はLinux環境でマルチスレッドを使い入力を受け付ける用のスレッドを作成した際に、入力用スレッドを任意のタイミングで削除する方法を作成します。

python内のInputをそのまま使用するとスレッドを削除できないのでその際の対処法となります。

この記事の内容

1. マルチスレッドの作成

2. 入力を受け取る方法

3.スレッドを削除する方法

ファイルを用意しよう

今回必要なファイルは3種類です。

  1. Python
  2. ソースファイル(この後に作成していきます)
  3. スレッドが削除されたことを確認するためのEditor(必要ならば)

Python環境構築

Pythonファイルを実行するにはPythonをインストールする必要があります。

インストールの方法に関しましては、下記のURLで紹介されているので試してみてください

PythonをLinuxにインストールする方法とそのメリットの完全ガイド
https://www.miraiserver.ne.jp/column/about_python-install-method/

Editorを使いスレッドの視覚化

VSCodeなどのスクリプティングエディターを使用することで、スレッドが削除されているかを視覚化して判別することができます。

下記リンクでVSCodeを使いPythonスクリプトを実行できるようにするまでの手順が書かれていますので、試してみてください。

Python開発環境を作る~その2:VS Codeのインストール~

https://note.com/ogs_digilife/n/n5cfb0e3fafed?magazine_key=mbb7c4124737f

実装してみよう

1.インプット用のスレッドを作成するためのマルチスレッドの実装

インプットを別スレッドで行うため、まずマルチスレッドを作成します。

import threading
import time

#スレッドを停止するためのフラグ
stop_event = threading.Event()

# マルチスレッドで動作する関数
def input_thread():
    while not stop_event.is_set():
        print("Please enter a command:")

# スレッドを1つ作成して起動
input_thread_instance = threading.Thread(target = input_thread, daemon = True)
input_thread_instance.start()

# 5秒後に入力スレッドのみを破壊
time.sleep(5)
stop_event.set() # スレッドに停止を指示

# メインスレッドはまだ動作可能
while True: #メインスレッドを無限ループで動作させる
    print("[Main Thread] Running...")

上記のコードでは、input_threadという関数をマルチスレッドで実行しています。

マルチスレッド自体は5秒後に削除してメインスレッドのみが残る形です。

流れをまとめると

input_threadのマルチスレッドを作成

->マルチスレッド先でプリントを行う

->5秒後にスレッドを破棄

->その後メインスレッドから出力を続ける

という形となり実行すると、

上記のような実行結果となります。

2.インプットスレッドの中身作成

インプットを行うために下記2つのモジュールをインポートします。

import select
import sys

あとはインプット待ちの時に入力ができるようにします。

def input_thread():
    while not stop_event.is_set():
        print("Please enter a command:")
        user_input = None # 初期化
        while True:
            if stop_event.is_set():
                break
            # 標準入力にデータがあるかチェック
            if select.select([sys.stdin], [], [], 0)[0]:
                user_input = sys.stdin.readline().strip() # 入力を1行取得
                print(f"User input received: {user_input}") # 入力を出力 
                if user_input.lower() == "exit": # exitが入力されたら修了
                    stop_event.set()
                    return
                break

これを実行すると、

上記のように入力を行うことができ、5秒後にはインプットのスレッドが破壊され、入力ができない状態となります。

まとめ

今回の処理については、CLIツールの入力処理や、マルチスレッドのサーバー管理、などで応用できると思われます。スレッドが立つたびに入力処理を入れたいけれども削除ができないから使えないなどの時に役立ちます。

関連記事