Pythonマルチスレッド-スレッドモジュール

デーモンスレッド

スレッドモジュールはデーモンスレッドをサポートし、その動作方法は次のとおりです。デーモンスレッドは通常、クライアントがサービスを要求するのを待機するサーバーです。クライアント要求がない場合、デーモンスレッドはアイドル状態です。スレッドがデーモンスレッドとして設定されている場合は、このスレッドは重要ではなく、プロセスの終了時にこのスレッドの実行が完了するのを待つ必要がないことを意味します。
スレッドをデーモンスレッドとして設定します。

thread.daemon = True

スレッドのガーディアンステータスを確認してください。この値を確認してください。

Pythonプログラム全体は、すべての非デーモンスレッドが終了した後に終了します。つまり、デーモンスレッドは、他の非デーモンスレッドの通常の動作を保証します。

スレッドを作成する

スレッドを使用してスレッドを作成します(最初の3つを選択することをお勧めします)。

  • Threadのインスタンスを作成し、それに関数を渡します。
  • Threadのインスタンスを作成し、呼び出し可能なクラスインスタンスに渡します。
  • Threadのサブクラスを派生させ、サブクラスのインスタンスを作成します。

スレッドのインスタンスを作成し、それに関数を渡します

コード

import threading
from time import sleep,ctime

loops = [4,2]

def loop(nloop,nsec):
    print('start loop ',nloop,' at:',ctime())
    sleep(nsec)
    print('loop ',nloop,' done at:',ctime())

def main():
    print('starting at:',ctime())
    threads = []
    nloops = range(len(loops))

    for i in nloops:
        t = threading.Thread(target=loop,args=(i,loops[i])) # 实例化Thread
        # loop为目标函数名,args为目标函数参数
        threads.append(t)

    for i in nloops:    # 开始线程
        threads[i].start()

    for i in nloops:    # 等待所有
        threads[i].join()   # 线程完成

    print('all DONE at:',ctime())

if __name__ == "__main__":
    main()

出力

starting at: Thu Sep 10 16:18:48 2020
start loop  0  at: Thu Sep 10 16:18:48 2020
start loop  1  at: Thu Sep 10 16:18:48 2020
loop  1  done at: Thu Sep 10 16:18:50 2020
loop  0  done at: Thu Sep 10 16:18:52 2020
all DONE at: Thu Sep 10 16:18:52 2020

join()メソッドはスレッドが終了するのを待つか、タイムアウト期間が指定されている場合はタイムアウト期間に達します。使用join()方法は、ロックが解除されるのを待つ無限ループよりも明確です(この種のロックはスピンロックの理由としても知られています)。如果主线程还有其他事情要去做,而不是等待这些线程完成(例如其他处理或者等待新的客户端请求),就可以不调用join()。join()方法只有在你需要等待线程完成的时候才是有用的。

Threadのインスタンスを作成し、呼び出し可能なクラスインスタンスに渡します

コード

import threading
from time import sleep,ctime

loops = [4,2]

class ThreadFunc(object):

    def __init__(self,func,args,name=''):
        self.name = name
        self.func = func
        self.args = args

    def __call__(self):
        self.func(*self.args)

def loop(nloop,nsec):
    print('start loop ',nloop,' at:',ctime())
    sleep(nsec)
    print('loop ',nloop,' done at:',ctime())

def main():
    print('starting at:',ctime())
    threads = []
    nloops = range(len(loops))

    for i in nloops:    # 创建所有线程
        t = threading.Thread(
            target=ThreadFunc(loop,(i,loops[i]),
            loop.__name__))
        threads.append(t)

    for i in nloops:    # 开始所有线程
        threads[i].start()

    for i in nloops:    # 等待完成
        threads[i].join()

    print('all DONE at:',ctime())

if __name__ == "__main__":
    main()

出力

starting at: Thu Sep 10 16:43:57 2020
start loop  0  at: Thu Sep 10 16:43:57 2020
start loop  1  at: Thu Sep 10 16:43:57 2020
loop  1  done at: Thu Sep 10 16:43:59 2020
loop  0  done at: Thu Sep 10 16:44:01 2020
all DONE at: Thu Sep 10 16:44:01 2020

Threadオブジェクトをインスタンス化すると、呼び出し可能なクラスThreadFuncもインスタンス化されます。同時に、このクラスは、関数パラメーターargs、関数自体func、および関数名の文字列名を保存します。新しいスレッドが作成されると、ThreadクラスのコードはThreadFuncオブジェクトを呼び出し、次に__call __()メソッドを呼び出します(このメソッドの機能は、クラスの()演算子のオーバーロードに似ているため、クラスインスタンスはオブジェクトは通常の関数と同じように呼び出すことができ、「オブジェクト名()」の形式で使用されます。`使用するパラメーターはすでにあるので、それらをThread()コンストラクターに渡す必要はなく、直接呼び出すだけです。

Threadのサブクラスを派生させ、サブクラスのインスタンスを作成します

コード

import threading
from time import sleep,ctime

loops = (4,2)

class MyThread(threading.Thread):

    def __init__(self,func,args,name=''):
        threading.Thread.__init__(self)
        self.name = name
        self.func = func
        self.args = args

    def run(self):
        self.func(*self.args)

def loop(nloop,nsec):
    print('start loop ',nloop,' at:',ctime())
    sleep(nsec)
    print('loop ',nloop,' done at:',ctime())

def main():
    print('starting at:',ctime())
    threads = []
    nloops = range(len(loops))

    for i in nloops:
        t = MyThread(loop,(i,loops[i]),loop.__name__)
        threads.append(t)

    for i in nloops:
        threads[i].start()

    for i in nloops:
        threads[i].join()

    print('all DONE at:',ctime())

if __name__ == '__main__':
    main()

出力

starting at: Thu Sep 10 17:18:35 2020
start loop  0  at: Thu Sep 10 17:18:35 2020
start loop  1  at: Thu Sep 10 17:18:35 2020
loop  1  done at: Thu Sep 10 17:18:37 2020
loop  0  done at: Thu Sep 10 17:18:39 2020
all DONE at: Thu Sep 10 17:18:39 2020

创建Thread的实例,传给它一个可调用的类实例派生サブクラスと比較して、2つの変更があります。

  1. MyThreadサブクラスのコンストラクターは、最初にその基本クラスのコンストラクターを呼び出す必要があります。
  2. 以前の特別なメソッド__call __()は、このサブクラスでrun()として記述する必要があります

おすすめ

転載: blog.csdn.net/XZ2585458279/article/details/108516586