4.python学習ノート:pythonマルチスレッドのthreadingモジュール


pythonマルチスレッドでのthreadingモジュール
threadingモジュール
pythonプログラミングでは、スレッドの処理には2つのモジュールがあります.threadとthreadingです.前の章では、スレッドの処理がクラスとオブジェクトに基づくより高いレベルのインタフェースであるthreadの使い方を紹介しました.実は本質的にthreadingモジュールは内部でthreadモジュールを使用してスレッドを表すオブジェクトとよく使われる同期化ツールを実現する.
前章の例ではthreadingを使用して再パッケージしました.
#!/usr/bin/env python

#-*-coding:utf-8-*-

import threading

class My_thread(threading.Thread):

    def __init__(self, my_id, count, mutex):
        self.my_id = my_id
        self.count = count
        self.mutex = mutex
        threading.Thread.__init__(self)

    def run(self):
        for i in range(self.count):
            with self.mutex:
                print ('[%s] => %s' % (self.my_id, i))

stdout_mutex = threading.Lock()
threads = []

if __name__ == '__main__':
    #start and append threads
    for i in range(10):
        thread = My_thread(i, 5, stdout_mutex)
        thread.start()
        threads.append(thread)


    #wait for thread ending...
    for thread in threads:
        thread.join()

    print ('Main thread exiting...')

ここではjoinを使用して、スレッドが終了したときに返される状態を受信し、メインスレッドが他のスレッドが終了した後にプログラムを終了するようにします.Myを作成するとthreadクラスオブジェクトが起動メソッドを呼び出すと、runメソッドは新しいスレッドでThreadクラスフレームワークで実行されます.
このスクリプトにはthreadingも使用されています.ロック()は操作の同期化を行った.
以前は、stdoutというファイル記述子リソースも各スレッド間で共有されているため、スレッド内の印刷操作をロックで同期する必要があった可能性があります.これにより、スレッドは、同じプロセスで共有される可能性のある任意のプロジェクトを同期する必要があることがわかります.
1.メモリ内の可変オブジェクト2.グローバル役割ドメインの名前.3.モジュールの内容;
例えば,整数を自己増加1演算し,この値の自己増加を各スレッドで2回実行する100スレッドを派生した.コードの例は次のとおりです.
#!/usr/bin/env python

#-*-coding:utf-8-*-

import threading
import time

count = 0

def adder(add_lock):
    global count
    with add_lock:
        count = count + 1
    time.sleep(0.25)
    with add_lock:
        count = count + 1

add_lock = threading.Lock()

if __name__ == '__main__':
    threads = []
    for i in range(100):
        thread = threading.Thread(target=adder, args=(add_lock,))
        thread.start()
        threads.append(thread)

    for thread in threads:
        thread.join()

    print(count)

threadingの追加インタフェース
*以下は伯楽のオンラインコンテンツを転載する
threading.Thread
Threadはthreadingモジュールで最も重要なクラスの1つであり、スレッドを作成するために使用できます.スレッドを作成するには2つの方法があります.1つはThreadクラスを継承することによってrunメソッドを書き換えることです.もう1つはthreadingを作成することですThreadオブジェクトは、その初期化関数(init)で呼び出し可能なオブジェクトをパラメータとして入力します.以下、それぞれ例を挙げて説明する.まずthreadingを継承することによってThreadクラスがスレッドを作成する例:
#coding=gbk
import threading, time, random
count = 0
class Counter(threading.Thread):
    def __init__(self, lock, threadName):
        '''@summary:      。 @param lock:    。 @param threadName:     。 '''
        super(Counter, self).__init__(name = threadName)  #  :             
   。
        self.lock = lock

    def run(self):
        '''@summary:     run  ,               。 '''
        global count
        self.lock.acquire()
        for i in xrange(10000):
            count = count + 1
        self.lock.release()
lock = threading.Lock()
for i in range(5):
    Counter(lock, "thread-" + str(i)).start()
time.sleep(2)   #         
print count

コードでは、threadingを継承するCounterクラスを作成しました.Thread.初期化関数は、2つのパラメータを受信します.1つは煩雑なオブジェクトで、もう1つはスレッドの名前です.Counterでは、親から継承されたrunメソッドが書き換えられ、runメソッドはグローバル変数を1つずつ10000増加します.次のコードでは、5つのCounterオブジェクトが作成され、それぞれstartメソッドが呼び出されます.最後に結果を印刷します.ここでrunメソッドとstartメソッドについて説明する:これらはいずれもThreadから継承され、run()メソッドはスレッドが開いた後に実行され、関連する論理をrunメソッドに書くことができる(通常runメソッドをアクティビティと呼ぶ[Activity]).start()メソッドは、スレッドを起動するために使用されます.
スレッドを作成する別の方法を見てみましょう.
import threading, time, random
count = 0
lock = threading.Lock()
def doAdd():
    '''@summary:      count      10000。 '''
    global count, lock
    lock.acquire()
    for i in xrange(10000):
        count = count + 1
    lock.release()
for i in range(5):
    threading.Thread(target = doAdd, args = (), name = 'thread-' + str(i)).start()
time.sleep(2)   #         
print count

このコードでは、グローバル変数countを1つずつ10000増加させる方法doAddを定義します.次に5つのThreadオブジェクトを作成し、関数オブジェクトdoAddをパラメータとしてその初期化関数に渡し、Threadオブジェクトのstartメソッドを呼び出し、スレッドが起動するとdoAdd関数が実行されます.ここではthreadingを紹介する必要があります.Threadクラスの初期化関数のプロトタイプ:
def init(self,group=None,target=None,name=None,args=(),kwargs={})パラメータgroupは、将来の拡張のために予約されている.パラメータtargetは呼び出し可能なオブジェクト(アクティブ[activity]とも呼ばれる)であり、スレッドが起動した後に実行されます.パラメータnameはスレッドの名前です.デフォルト値は「Thread-N」で、Nは数値です.パラメータargsとkwargsはtargetを呼び出すときのパラメータリストとキーワードパラメータをそれぞれ表します.
Threadクラスでは、次の一般的なメソッドとプロパティも定義されています.getName() Thread.setName() Thread.name
スレッドの取得と設定に使用する名前.Thread.ident
スレッドの識別子を取得します.スレッド識別子は、start()メソッドが呼び出された後にのみ有効な非ゼロ整数です.そうしないと、Noneのみが返されます.Thread.is_alive() Thread.isAlive()
スレッドがアクティブかどうかを判断します.スレッドはstart()メソッドを呼び出してスレッドを起動し、run()メソッドの実行が完了したり、未処理の例外が発生して中断したりするまでアクティブになります.Thread.join([timeout])
呼び出しjoinは、呼び出されたスレッドの実行が終了またはタイムアウトするまで、プライマリ・コール・スレッドをブロックします.パラメータtimeoutは、タイムアウト時間を表す数値タイプであり、パラメータが指定されていない場合、プライマリ・コール・スレッドは、コール・スレッドが終了するまでブロックされます.
上記の例ではjoinの使い方を示した.
threading.RLockとthreading.Lock
この2つの煩雑な主な違いは、RLockが同じスレッドで複数のacquireを許可することである.ロックはこのような状況を許さない.注意:RLockを使用する場合、acquireとreleaseはペアで表示される必要があります.すなわち、n回のacquireが呼び出され、n回のreleaseが本当に使用された煩わしさを解放するには、n回のreleaseが呼び出されなければなりません.
threadingモジュールにはいくつかの一般的な方法が紹介されていません:threading.active_count() threading.activeCount()
現在アクティブな(alive)スレッドの数を取得します.threading.current_thread() threading.currentThread()
現在のスレッドオブジェクト(Thread object)を取得します.threading.enumerate()
現在のすべてのアクティブなスレッドのリストを取得します.threading.settrace(func)
run()が実行される前に呼び出されるトレース関数を設定します.threading.setprofile(func)
run()の実行後に呼び出すトレース関数を設定します.
python上のthreadingモジュールの使用については、pythonマニュアルを参照して、より詳細な学習を行うことができます.https://docs.python.org/2/library/threading.html#module-threading