検索
  • サインイン
  • サインアップ
パスワードのリセットが成功しました

興味のあるプロジェクトをフォローし、それらに関する最新ニュースをチェックしてください

Python マルチスレッド

コレクション 335
リーディング 129468
更新時間 2016-09-11

マルチスレッドは、複数の異なるプログラムを同時に実行することに似ています。 マルチスレッドには次の利点があります:

  • スレッドを使用すると、長期プログラムのタスクをバックグラウンドで処理できます。

  • ユーザー インターフェイスをより魅力的にすることができ、ユーザーがボタンをクリックして特定のイベントの処理をトリガーすると、プログレス バーがポップアップして処理の進行状況を表示できます

  • プログラムが高速化される可能性があります

  • スレッドは、ユーザー入力、ファイルの読み取りと書き込み、ネットワークでのデータの送受信などの待機中のタスクの実装でより便利です。この場合、メモリ使用量などの貴重なリソースを解放できます。

スレッドは、実行中のプロセスとは依然として異なります。それぞれの独立したスレッドには、プログラム実行のエントリ ポイント、順次実行シーケンス、およびプログラムの終了ポイントがあります。ただし、スレッドは独立して実行できず、アプリケーション プログラム内に存在する必要があり、アプリケーション プログラムは複数のスレッドの実行制御を提供します。

各スレッドには、スレッドのコンテキストと呼ばれる独自の CPU レジスタのセットがあり、スレッドが最後に実行されたときの CPU レジスタの状態を反映します。

命令ポインタとスタック ポインタ レジスタは、スレッド コンテキストで最も重要な 2 つのレジスタであり、スレッドは常にプロセス コンテキストで実行されます。これらのアドレスは、スレッドを所有するプロセスのアドレス空間内のメモリをマークするために使用されます。

  • スレッドはプリエンプト (中断) できます。

  • 他のスレッドの実行中に、スレッドを一時的に保留 (スリープとも呼ばれる) することができます。これをスレッド バックオフといいます。


Python スレッドの学習を始めましょう

Python でスレッドを使用するには、スレッド オブジェクトをラップする関数またはクラスの 2 つの方法があります。

機能: スレッドモジュールの start_new_thread() 関数を呼び出して、新しいスレッドを生成します。構文は次のとおりです:

thread.start_new_thread ( function, args[, kwargs] )

パラメータの説明:

  • function - スレッド関数。

  • args - スレッド関数に渡されるパラメータ。タプル型である必要があります。

  • kwargs - オプションのパラメータ。

例:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import thread
import time

# 为线程定义一个函数
def print_time( threadName, delay):
   count = 0
   while count < 5:
      time.sleep(delay)
      count += 1
      print "%s: %s" % ( threadName, time.ctime(time.time()) )

# 创建两个线程
try:
   thread.start_new_thread( print_time, ("Thread-1", 2, ) )
   thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
   print "Error: unable to start thread"

while 1:
   pass

上記のプログラムを実行した出力結果は次のとおりです:

Thread-1: Thu Jan 22 15:42:17 2009
Thread-1: Thu Jan 22 15:42:19 2009
Thread-2: Thu Jan 22 15:42:19 2009
Thread-1: Thu Jan 22 15:42:21 2009
Thread-2: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:23 2009
Thread-1: Thu Jan 22 15:42:25 2009
Thread-2: Thu Jan 22 15:42:27 2009
Thread-2: Thu Jan 22 15:42:31 2009
Thread-2: Thu Jan 22 15:42:35 2009

スレッドの終了は、通常、スレッド関数の自然な終了に依存します。また、スレッド関数で thread.exit() を呼び出すこともできます。スレッド関数。スレッドを終了する目的を達成するために SystemExit 例外をスローします。


スレッド モジュール

Python は、スレッドとスレッドという 2 つの標準ライブラリを通じてスレッドのサポートを提供します。 thread は、低レベルのプリミティブなスレッドと単純なロックを提供します。

スレッド モジュールによって提供されるその他のメソッド:

  • threading.currentThread(): 現在のスレッド変数を返します。

  • threading.enumerate(): 実行中のスレッドを含むリストを返します。実行中とは、スレッドの開始後から終了までを指します。ただし、起動前と終了後のスレッドは除きます。

  • threading.activeCount(): 実行中のスレッドの数を返します。これは、len(threading.enumerate()) と同じ結果になります。

使用方法に加えて、スレッド モジュールはスレッドを処理するための Thread クラスも提供します。 Thread クラスは次のメソッドを提供します:

  • run(): スレッドのアクティビティを表すために使用されるメソッド。

  • start():スレッドアクティビティを開始します。


  • join([time]): スレッドが終了するまで待ちます。これにより、スレッドの join() メソッドが異常終了 (通常終了するか、未処理の例外をスロー) が呼び出されるか、またはオプションのタイムアウトが発生するまで、呼び出しスレッドがブロックされます。

  • isAlive(): スレッドがアクティブかどうかを返します。

  • getName(): スレッド名を返します。

  • setName(): スレッド名を設定します。


Threadingモジュールを使用してスレッドを作成します

Threadingモジュールを使用してスレッドを作成し、threading.Threadから直接継承し、__init__メソッドとrunメソッドを書き換えます:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import threading
import time

exitFlag = 0

class myThread (threading.Thread):   #继承父类threading.Thread
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):                   #把要执行的代码写到run函数里面 线程在创建后会直接运行run函数 
        print "Starting " + self.name
        print_time(self.name, self.counter, 5)
        print "Exiting " + self.name

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            thread.exit()
        time.sleep(delay)
        print "%s: %s" % (threadName, time.ctime(time.time()))
        counter -= 1

# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启线程
thread1.start()
thread2.start()

print "Exiting Main Thread"

上記の実行結果プログラムは次のとおりです。

Starting Thread-1
Starting Thread-2
Exiting Main Thread
Thread-1: Thu Mar 21 09:10:03 2013
Thread-1: Thu Mar 21 09:10:04 2013
Thread-2: Thu Mar 21 09:10:04 2013
Thread-1: Thu Mar 21 09:10:05 2013
Thread-1: Thu Mar 21 09:10:06 2013
Thread-2: Thu Mar 21 09:10:06 2013
Thread-1: Thu Mar 21 09:10:07 2013
Exiting Thread-1
Thread-2: Thu Mar 21 09:10:08 2013
Thread-2: Thu Mar 21 09:10:10 2013
Thread-2: Thu Mar 21 09:10:12 2013
Exiting Thread-2


スレッドの同期

複数のスレッドが共同して特定のデータを変更すると、予測できない結果が発生する可能性があります。データの正確性を確保するには、複数のスレッドを同期する必要があります。

単純なスレッド同期は、Thread オブジェクトの Lock と Rlock を使用することで実現できます。両方のオブジェクトには、一度に 1 つのスレッドのみで操作する必要があるデータの場合、操作を Acquire メソッドと Release メソッドに配置できます。メソッド間のリリース。以下の通り:

マルチスレッドの利点は、複数のタスクを同時に実行できることです (少なくともそう感じられます)。ただし、スレッドがデータを共有する必要がある場合、データの非同期の問題が発生する可能性があります。

次の状況を考えてみましょう。リスト内のすべての要素が 0 で、スレッド「set」は後ろから前にすべての要素を 1 に変更し、スレッド「print」はリストを前から後ろに読み取って印刷する責任があります。

その後、おそらくスレッド「set」が変更を開始すると、スレッド「print」がリストを出力し、出力は半分が 0 で半分が 1 になります。これがデータの非同期です。この状況を回避するために、ロックの概念が導入されました。

ロックには、ロックとロック解除の 2 つの状態があります。 「set」などのスレッドが共有データにアクセスしたい場合は、まずロックを取得する必要があります。「print」などの別のスレッドがすでにロックを取得している場合は、スレッド「set」を一時停止させます。これは同期ブロックです。スレッド「Print」まで アクセスが完了してロックが解除された後、スレッド「set」を続行させます。

この処理により、リストを印刷する際に全て0か全て1が出力されるようになり、半分0と半分1という恥ずかしい場面はなくなりました。

例:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import threading
import time

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print "Starting " + self.name
       # 获得锁,成功获得锁定后返回True
       # 可选的timeout参数不填时将一直阻塞直到获得锁定
       # 否则超时后将返回False
        threadLock.acquire()
        print_time(self.name, self.counter, 3)
        # 释放锁
        threadLock.release()

def print_time(threadName, delay, counter):
    while counter:
        time.sleep(delay)
        print "%s: %s" % (threadName, time.ctime(time.time()))
        counter -= 1

threadLock = threading.Lock()
threads = []

# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()

# 添加线程到线程列表
threads.append(thread1)
threads.append(thread2)

# 等待所有线程完成
for t in threads:
    t.join()
print "Exiting Main Thread"


スレッド優先度キュー (キュー)

Python の Queue モジュールは、FIFO (先入れ先出し) キュー Queue、LIFO (後入れ先出し) キュー LifoQueue などの同期のスレッドセーフ キュー クラスを提供します。優先キューPriorityQueue。これらのキューはロック プリミティブを実装しており、マルチスレッドで直接使用できます。キューを使用して、スレッド間の同期を実現できます。

Queue モジュールでよく使用されるメソッド:


  • Queue.qsize() キューのサイズを返します

  • Queue.empty() キューが空の場合は True を返し、それ以外の場合は False を返します

  • Queue.full() キューがいっぱいの場合は戻りますTrue、そうでない場合は False

  • Queue.full は maxsize size に対応します

  • Queue.get([block[, timeout]]) でキューを取得し、タイムアウト待ち時間

  • Queue.get_nowait() は同等ですQueue.get(False)へ

  • Queue.put(item)はキューに書き込み、タイムアウト待ち時間

  • Queue.put_nowait(item)はQueue.put(item, False)と同等です

  • Queue.task_done() ジョブの完了後、Queue.task_done() 関数はタスクが完了したキューにシグナルを送信します

  • Queue.join() は実際には、他の操作を実行する前にキューが空になるまで待機することを意味します

例:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import Queue
import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q
    def run(self):
        print "Starting " + self.name
        process_data(self.name, self.q)
        print "Exiting " + self.name

def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
            queueLock.release()
            print "%s processing %s" % (threadName, data)
        else:
            queueLock.release()
        time.sleep(1)

threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = Queue.Queue(10)
threads = []
threadID = 1

# 创建新线程
for tName in threadList:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1

# 填充队列
queueLock.acquire()
for word in nameList:
    workQueue.put(word)
queueLock.release()

# 等待队列清空
while not workQueue.empty():
    pass

# 通知线程是时候退出
exitFlag = 1

# 等待所有线程完成
for t in threads:
    t.join()
print "Exiting Main Thread"

上記プログラム 実行結果:

Starting Thread-1
Starting Thread-2
Starting Thread-3
Thread-1 processing One
Thread-2 processing Two
Thread-3 processing Three
Thread-1 processing Four
Thread-2 processing Five
Exiting Thread-3
Exiting Thread-1
Exiting Thread-2
Exiting Main Thread

ホットAIツール
Undress AI Tool
Undress AI Tool

脱衣画像を無料で

AI Clothes Remover
AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undresser.AI Undress
Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

Stock Market GPT
Stock Market GPT

AIを活用した投資調査により賢明な意思決定を実現

人気のツール
メモ帳++7.3.1
メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版
SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6
ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版
SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)