Pythonの道(第4の15)スレッドイベントのイベント、条件、条件、タイマータイマー、スレッドキュー

まず、イベントのイベント

事象(イベント)のイベント処理メカニズムは:グローバルフラグがtrueの場合、この方法は場合event.waitなり値がFalseである場合、フラグは、プログラムが実行されevent.wait方法はブロックする内蔵マークフラグを定義しますもはやブロックされません。

 

イベントは、実際に条件の簡易版です。イベントはロックされていない、それがブロックされた状態にスレッドを同期することはできません。

イベント()

  • フラグがTrueに設定されており、待機状態にあるすべてのスレッドが回復操作をブロック通知:()を設定します。

  • クリア():フラグがFalseに設定されています。

  • (タイムアウト)待つ:フラグはすぐに返されますTrueであれば、そうでない場合は、待って設定された他のスレッドの呼び出しを待つためにブロックされたスレッドをブロックされました()。

  • ISSET():、内蔵のフラグの状態を取得しますTrueまたはFalseを返します。

 

重要な特徴は、各スレッドが別のスレッドの実行と予測できない状態であることです。プログラム内の他のスレッドがスレッドの状態を判断して、その次のアクションを決定する必要がある場合は、スレッド同期の問題が非常に困難になります。これらの問題を解決するために、我々は、Eventオブジェクトのスレッドライブラリを使用する必要があります。オブジェクトは、スレッドが特定のイベントの発生を待つことを可能にする信号フラグによってスレッドのセットを含みます。

手順:最初のケースの後、信号イベントオブジェクトフラグが偽に設定されています。そこEventオブジェクトを待つスレッドがあり、かつEventオブジェクトの符号がfalseの場合フラグが真されるまで、そのスレッドがブロックされます。Eventオブジェクトフラグを通知しますつのスレッドがtrueに設定されている場合は、このイベントオブジェクトを待っている全てのスレッドをウェイクアップします。スレッドがオブジェクトとして設定されている真のイベントを待っている場合、それは、イベントを無視し続けます。

使用シナリオ:

我々は唯一の接続が成功しなかった場合、我々は再接続しようと、MySQLサーバに接続するためのスレッドを扱う人のための通常のサービスをリンクする前に必ずMySQLを作りたい、複数のワーカースレッドは、MySQLをリンクしようとしています。その後、我々は、各ワーカースレッドの接続の動作を調整するための機構をthreading.Event使用することができます

スレッドからのイベントのインポートをスレッディング
インポート時間
インポートランダム
:DEFのconnect_db(E)
    time.sleep(random.randint(0,3))
    e.set()
DEFのcheck_web(E):
    COUNT = 1。
    time.sleep( 1)
    しばらくCOUNT <4:
        e.wait(0.5)#状態はFalse、あなただけ0.5秒待つことができます終了
        e.is_set()した場合:
            "!%sの倍のデータベース・リンクの成功"を印刷(COUNT%)が
            BREAK 
        他に:
            ( "%sの二次リンクデータベースに障害が発生した!" COUNT%)をプリント
            COUNT + = 1。
    他:
        昇給TimeoutError( "データベース・リンクタイムアウト")
E =イベント()
T1 =スレッド(対象= check_web、引数=(E、 )) 
T2 =スレッド(対象= connect_db、引数=(E、 ))
t1.start()
t2.start()

  

第二に、条件条件

条件はシニアささいなものとして理解することができ、それは、私たちは、複雑なスレッドの同期の問題を制御することができますRLOCK機能をロックよりも、より高度な提供しています。threadiong.Conditionが内部(デフォルトはRLOCKある)些細なオブジェクトを保持し、あなたは、ささいな引数としてときにオブジェクトCondigtionオブジェクトを作成することができます。

条件はまた、実際に、それは単にそれの内側に対応するメソッド些細なオブジェクトを呼び出して取得、解除方法、その意味ささいな取得と一致し、解除方法を、提供します。

条件は、(特に注意して:これらのメソッドはそれ以外の場合は例外RuntimeError例外を報告します、職業周防(取得)した後に呼び出すことができます。)以下のメソッドを提供します。

 

  • Condition.wait([タイムアウト]):

    (それが提供される場合、タイムアウトパラメータ)スレッドがウェイクアップ通知を受信するまで中断またはタイムアウトされている間、周防が占有内部待機を解除する方法。スレッドがウェイクアップして再占める周防すると、プログラムは実行を継続します。

  • Condition.notify():

    (保留中のスレッドがある場合は)中断されたスレッドを覚まします。注:通知()メソッドは、占有ささいを解放しません。

  • Condition.notify_all()Condition.notifyAll()

    (保留中のスレッドがある場合は)保留中のすべてのスレッドを覚まします。注:これらのメソッドは、占有ささいを放出しません。

 

 



条件条件のために、からスレッドのインポートをスレッディング
(CON、I)DEF FUNC:
    con.acquire()
    con.wait()
    印刷( "%sの実行スレッドの" %のI)
    con.release()
条件条件のCON = () 範囲内I(10)のための
    スレッド(ターゲット= FUNC、引数=(CON、I))スタート()。
しばらく真:
    NUM = INPUT( ">>>")ストリップ()。
    (num.isdigit IF ):
        NUM = INT(NUM)
    他:BREAK 
    con.acquire()
    con.notify(NUM)#通知複数のスレッドが実行できるある
    con.release()
条件条件Pythonは、オブジェクトが複雑なスレッドの同期化を提供するための提供位サポート。
条件条件#変数の条件は、メソッドを取得し解放するロック類似を提供することに加えて、参照される
#も待ち時間を提供し、方法を通知されます。スレッドは、最初の状態変数を取得し、その後、条件の数を決定します。 
待ち条件が満たされない場合位、条件が満たされた場合、いくつかの処理条件の変化、
#は通知方法を介して、他のスレッドに通知し、通知を受信した後、待機状態にある他のスレッドは、再判定条件であろう。
複雑な同期の問題を解決するために、#は、このプロセスを繰り返します。

  


分析:プログラム内の数は、スレッドをきっかけにループのため、デジタル入力の数はどのように多くのスレッドを実行して入力します。

 

第三に、タイマータイマー

タイマー:機能一定時間毎に呼び出し、関数を呼び出すために随時に達成する必要がある場合は、その後、我々は機能タイマを呼ぶだろう、再びタイマーを設定します。タイマースレッドは、派生クラスです。

 

タイマーは、サブThreadクラスを継承し、スレッドのサブクラスで、スレッドクラスは能力や性格のスレッドを持っています。このクラスは、どのくらいの機能の実行を定義するために使用されます。

その例としては、目的関数の実際の実装前に、あなたはそれをキャンセルすることができ、スレッドの目的関数の実装を延期する機能です。

タイマー()

最初のパラメータは、すべての時間間隔を送信され、

伝達関数functionの後、この機能を実行する秒数を越えタスクを実行するには

モード引数のkwargsからを渡す関数パラメータへ

 

タイマーは、スレッドのモジュールを使用し、それぞれのタイマーを開始、スレッドを開始します

 

 

 


インポートタイマスレッドから
インポート時間
:DEF(x、y)を追加
    印刷(X + Y)
T =タイマ(10、追加、引数の= [4,5、])
t.start()
時間。睡眠(2)
t.cancel()
印刷( "===終了===")

  


 分析:Timerオブジェクトが待機状態にあるstartメソッドを実行した後、それは、追加機能の実行後に10秒間待機します。一方、待機期間追加機能の実装前に、メソッドを使用して、メインスレッドは、子スレッドが関数の実行の終了をスキップしますキャンセル。

 


指定されたn個のアクションを実行する秒後に#タイマー
タイマースレッディングインポートから
インポート時間
DEF FUNC():
    印刷(「実行時刻同期」)
しばらく真:
    タイマー(5、FUNC).start()#(注)このことスレッドは非同期で、最初の文の実行、その後すぐに)(time.sleepを実行し、
    5秒間待って、現時点で5秒間、およびtime.sleepを()待機した後に実行#タイマFUNC、再実行してタイマー()
    の時間.sleep(5)

  

 

 

第四に、スレッドキュー

主にキューのスレッド間通信を実現するために使用される複数のキューキューのブロッキングモジュールを提供しています。メインキューモジュール三個のキューを表す3つのカテゴリを提供して、主な違いは、入口キュー異なるキューです。

簡単に約3キュークラス次のように:

  • Queue.qsizeは():キューの実際のサイズ、キューに含まれる、すなわちいくつかの要素を返します。

  • Queue.empty():キューが空であるかどうか。

  • Queue.full():キューが満杯であるかどうか。

  • Queue.put(アイテム、ブロック= Trueの場合、タイムアウト=なし):キュー要素に入れ。キューが既に満杯であり、ブロックパラメータは、(ブロッキング)が真である場合、現在のスレッドは、タイムアウトがタイムアウトがNoneに設定されている場合、時間をブロック指定し、ブロックされているキューの要素が消費されるまでブロックを表し、キューが既に満杯である場合、及びブロックパラメータは、(ブロックされていない)Falseで直接queue.FULL例外を発生させました。

  • Queue.put_nowait(アイテム):ブロックせずに、キュー要素に入れ。これは、パラメータブロック内のメソッドではFalseに対応しています。

  • Queue.get(アイテム、ブロック= Trueの場合、タイムアウト=なし):キューから要素(要素の消費量)を取り外します。キューがいっぱいになると、ブロックパラメータが(ブロッキング)が真である場合、現在のスレッドがブロックされているタイムアウトがNoneに設定されている場合、すべての要素がキューに配置されるまで、タイムアウトを指定遮断時間は、ブロックを表し、キューが既に空である場合、そして、ブロックパラメータは、(ブロックされていない)Falseで、直接queue.EMPTY例外を発生させました。

  • Queue.get_nowait(アイテム):ブロックせずにキューから要素を削除します。これは、パラメータブロック内のメソッドではFalseに対応しています。

  • キューの長さを定義するために使用Queue.Queue(MAXSIZE = 0)#FIFO、それがキューが1つの未満MAXSIZE無限長であることを示す場合、

  • Queue.LifoQueue(MAXSIZE = 0)#LIFO、それは無限の長さの1つの未満MAXSIZEキューを表す場合

  • task_done前に()#は、チームが完了したタスクを意味します。スレッドは、コンシューマ・キューによって呼び出されます。それぞれの現在のタスクが(参加配られた場合には()仕事を得るために呼び出します、次のtask_done()の呼び出し)がキューに指示がブロックされ、それは、つまり(キュー内のすべてのタスクが処理されるたびに実行を再開しますタスクチームによって呼び出される())に対応するtask_done()の呼び出しに入れています。

  • キュー内のすべてのタスクが処分されるまで()#ブロック呼び出し元のスレッドに参加します。限り、データがキューイングされるように、未完了のタスクの数が増加します。ときに、消費者のスレッドがブロックされていない((平均消費者が作業を行い、作業を完了している)、未完了のタスクの数が削減されます。場合は0まで未完了のタスクの数、(参加)task_doneを呼び出します。

 

キューの3つの異なるクラス

Q =キュー(MAXSIZE)は:FIFO(先入れ先出しで作成し 、 FIFO)キュー。MAXSIZEはお金を入れて、キュー内のエントリの最大数です。
それは省略、またはMAXSIZEパラメータが0に設定されている場合は、キューのサイズは無限大になります。Q = LifoQueue(MAXSIZE):(後入れ先出しLIFOを作成し 、 キュー(スタック)うち最初で最後)。Q =優先度つきキュー(MAXSIZE)は:前記優先項目に応じてローからハイに並ぶ、プライオリティキューを作成します。このような待ち行列エントリは、タプルの形式で(優先順位、データ)、前記優先識別番号の優先すべきとき。




プロセスキュー#インポートキューのマルチプロセッシングで使用
インポートキュー
#Q1を= Queue.Queue()#のFIFOの
エラーが空のかかる場合#q1.get_nowait()#は、直接のアクセスをブロックしません
#のq1.put_nowaitを(2) #直接入金をブロックしない堆積物が完全なエラーである場合、
#q1.get()
#q1.put(1)
実際には、Q2 = queue.LifoQueue()#スタック、後前進
」(q2.put ")
q2.put(" B ")
q2.put(" C「)
プリント(q2.get())
に配置された抽出されたオブジェクトに基づいてQ3 = queue.PriorityQueue()#プライオリティキュー、優先決意
Q3 .get((20、 "A")である)
q3.get((10、 "C"))
q3.get((0、 "B"))
q3.get(( - 10、 "D"))#デジタル小さい方の優先順位を取り出し
q3.get((30、 "E"))
印刷(q3.getを())

  


プロデューサーの消費者モデル

輸入スレッド
インポート時間
キューのインポートキューから
:DEF put_id()
    I = 0 
    しばらく真:
        I = I + 1枚
        の印刷( "添加数据"、I、id_queue.qsize())
        time.sleep(1)
        id_queue.put (I)
DEF(M)GET_ID:
    一方TRUE:
        I = id_queue.get()
        プリント( "线程"、M '取值'、i)は
なら__name__ == "__main__":
    id_queue =キュー( 10)
    のTh1 = threading.Thread(目標= put_id)
    のTh2 = threading.Thread(目標= GET_ID、引数=(2)) 
    Th3の= threading.Thread(目標= GET_ID、引数=(3))
    TH5 = threading.Thread(目標= GET_ID、引数=(4))
    TH4 = threading.Thread(目標= GET_ID、引数=(5))
    Th1.start()
    Th2.start()
    Th3.start()
    Th4.start()
    Th5.start()

  

 

 

 

おすすめ

転載: www.cnblogs.com/Nicholas0707/p/11441033.html