ホームページ バックエンド開発 Python チュートリアル Pythonのマルチスレッド、ロック、イベントの仕組みの簡単な使い方を詳しく解説

Pythonのマルチスレッド、ロック、イベントの仕組みの簡単な使い方を詳しく解説

Apr 27, 2018 am 11:52 AM
event python イベント

この記事では主に Python のマルチスレッド、ロック、イベントの仕組みについて簡単に紹介しますので、参考にしてください。一緒に見てみましょう

スレッドとプロセス

1. スレッドは、それを作成したプロセスのアドレス空間を共有し、プロセスは独自のアドレス空間を持ちます


2.プロセスのデータとスレッドは相互にアクセスできます

3. スレッド間のデータは独立しています

4. 子プロセスは、開始後にスレッドのデータをコピーします

5.プロセスは子プロセスを強制終了することしかできませんが、データを交換することはできません。

6. スレッド内のデータを変更すると他のスレッドに影響しますが、プロセスへの変更は子プロセスには影響しません


threading.Thread

Threadスレッド モジュール 1 の中で最も重要なクラスです。これを使用してスレッドを作成できます。スレッドを作成するには 2 つの方法があります。1 つは Thread クラスを継承し、その run メソッドをオーバーライドする方法です。もう 1 つは、threading.Thread オブジェクトを作成し、呼び出し可能なオブジェクトをその初期化関数 (__init__) のパラメーターとして渡す方法です。

まず、スレッドを継承してスレッドを作成する例を見てみましょう。Thread クラス:

import threading
import time

class MyThread(threading.Thread):
 def __init__(self, arg):
  # super(MyThread, self).__init__() # 新式类继承原有方法写法
  threading.Thread.__init__(self)
  self.arg = arg

 def run(self):
  time.sleep(2)
  print(self.arg)

for i in range(10):
 thread = MyThread(i)
 print(thread.name)
 thread.start()
ログイン後にコピー

スレッドを作成する別の方法:

import threading
import time

def process(arg):
 time.sleep(2)
 print(arg)

for i in range(10):
 t = threading.Thread(target=process, args=(i,))
 print(t.name)
 t.start()
ログイン後にコピー

Thread クラスは、次の一般的なメソッドも定義します。および属性:

Thread.getName() スレッド名を取得します


Thread.setName() スレッド名を設定します


Thread.name スレッド名


Thread.ident スレッドの識別子を取得します。スレッド識別子はゼロ以外の整数です。それ以外の場合は、スレッドがアクティブかどうかを判断するために None

を返すだけです。スレッドを開始するために start() メソッドが呼び出されてから、run() メソッドが完了するか、未処理の例外によって中断されるまで、スレッドはアクティブ化されます

Thread.is_alive()

Thread.isAlive()

Thread . join([timeout]) Thread.join を呼び出すと、呼び出されたスレッドが実行を終了するかタイムアウトになるまで、呼び出し元のスレッドがブロックされます。パラメータ timeout はタイムアウト時間を示す数値型です。このパラメータが指定されていない場合、呼び出されたスレッドは、呼び出されたスレッドが終了するまでブロックされます


Python GIL (Global Interpreter Lock)

GIL は、 Python の機能。これは、Python パーサー (CPython) を実装するときに導入された概念です。 C++ が一連の言語 (文法) 標準であるのと同様に、さまざまなコンパイラを使用して実行可能コードにコンパイルできます。 GCC、INTEL C++、Visual C++などの有名なコンパイラ。 Python にも同じことが当てはまります。CPython、PyPy、Psyco などの異なる Python 実行環境を通じて、同じコードを実行できます。たとえば、JPython には GIL がありません。ただし、ほとんどの環境では CPython がデフォルトの Python 実行環境です。したがって、多くの人の概念では、CPython は Python であり、GIL は Python 言語の欠陥であると当然のことと考えています。ここで明確にしておきますが、GIL は Python の機能ではなく、Python は GIL に依存する必要はまったくありません。


スレッドロックの使用法:

# 锁:GIL 全局解释器 它是为了保证线程在运行过程中不被抢占
number = 0
lock = threading.RLock() # 创建锁


def run(num):
 lock.acquire() # 加锁
 global number
 number += 1
 print(number)
 time.sleep(2)
 lock.release() # 释放锁

for i in range(10):
 t = threading.Thread(target=run, args=(i, ))
 t.start()
ログイン後にコピー

Join & Daemon

メインスレッドAでサブスレッドBが作成され、メインスレッドAでB.setDaemon()が呼び出されます。は、メインスレッド A がデーモンスレッドとして設定されていることを意味します。このとき、メインスレッド A の実行が終了すると、サブスレッド B が完了するかどうかに関係なく、メインスレッド A とともに終了します。 setDaemon メソッドの基本的には join と同じですが、その逆です。さらに、特に注意すべき点がもう 1 つあります。start() メソッドを呼び出す前に設定する必要があります。デーモン スレッドとして設定されていない場合、プログラムは無期限に停止されます。

class MyThread1(threading.Thread):
 def __init__(self):
  threading.Thread.__init__(self)

 def run(self):
  print("thread start")
  time.sleep(3)
  print('thread end')

print('main start')
thread1 = MyThread1()
# thread1.setDaemon(True)  # 设置子线程是否跟随主线程一起结束
thread1.start()
time.sleep(1)
print('satrt join')
# thread1.join() # 使主线程阻塞,直至子线程运行完毕再继续主线程
print('end join')
ログイン後にコピー

def run(n):
 print('[%s]------running----\n' % n)
 time.sleep(2)
 print('--done--')


def main():
 for i in range(5):
  t = threading.Thread(target=run, args=[i,])
  t.start()
  # t.join()
  print('starting thread', t.getName())


m = threading.Thread(target=main,args=[])
# m.setDaemon(True) # 将主线程设置为Daemon线程,它退出时,其它子线程会同时退出,不管是否执行完任务
m.start()
# m.join() # 使主线程阻塞,直至子线程运行完毕再继续主线程
print("---main thread done----")
ログイン後にコピー

スレッドロック(ミューテックス)

1つのプロセスの下で複数のスレッドを開始でき、複数のスレッドが親プロセスのメモリ空間を共有します。つまり、各スレッドはアクセスできます。このとき、2 つのスレッドが同じデータを同時に変更したい場合はどうなりますか?

num = 100 # 设定一个共享变量
def subNum():
 global num # 在每个线程中都获取这个全局变量
 print('--get num:', num)
 time.sleep(2)
 num -= 1 # 对此公共变量进行-1操作
thread_list = []
for i in range(100):
 t = threading.Thread(target=subNum)
 t.start()
 thread_list.append(t)
for t in thread_list: # 等待所有线程执行完毕
 t.join()
print('final num:', num)
ログイン後にコピー

# 加锁版本
def subNum():
 global num # 在每个线程中都获取这个全局变量
 print('--get num:', num)
 time.sleep(1)
 lock.acquire() # 修改数据前加锁
 num -= 1 # 对此公共变量进行-1操作
 lock.release() # 修改后释放

num = 100 # 设定一个共享变量
thread_list = []
lock = threading.Lock() # 生成全局锁
for i in range(100):
 t = threading.Thread(target=subNum)
 t.start()
 thread_list.append(t)
for t in thread_list: # 等待所有线程执行完毕
 t.join()
print('final num:', num)
ログイン後にコピー

Rlock と Lock の違い:

RLock は同じスレッド内で複数回取得できます。しかし、ロックはそれを許しません。そうしないと、無限ループが発生し、プログラムはどのロックを解除すればよいのかわかりません。注: RLock を使用する場合、acquire と release はペアで指定する必要があります。つまり、acquire が n 回呼び出された場合、占有されているロックを実際に解放するには release を n 回呼び出す必要があります

Events

Python は Event オブジェクトを提供しますスレッド間通信の場合、これはスレッドによって設定されたシグナル フラグです。シグナル フラグが true の場合、他のスレッドはシグナルに接続されるまで待機します。

イベントオブジェクトは、スレッド間の通信を実現するためのシグナルの設定、シグナルのクリア、待機などを提供する単純なスレッド通信メカニズムを実装します。

event = threading.Event() イベントを作成します

1 シグナルを設定します

event.set()

Eventのset()メソッドを使用して、Eventオブジェクト内のシグナルフラグをtrueに設定します。 Event オブジェクトは、内部信号フラグのステータスを決定するための isSet() メソッドを提供します。

イベントオブジェクトのset()メソッドを使用した場合、isSet()メソッドはtrueを返す

2 シグナルをクリア

event.clear()

使用Event对象的clear()方法可以清除Event对象内部的信号标志,即将其设为假,当使用Event的clear方法后,isSet()方法返回假

3 等待
event.wait()

Event对象wait的方法只有在内部信号为真的时候才会很快的执行并完成返回。当Event对象的内部信号标志位假时,
则wait方法一直等待到其为真时才返回。也就是说必须set新号标志位真

def do(event):
 print('start')
 event.wait()
 print('execute')

event_obj = threading.Event()
for i in range(10):
 t = threading.Thread(target=do, args=(event_obj,))
 t.start()

event_obj.clear()
inp = input('输入内容:')
if inp == 'true':
 event_obj.set()
ログイン後にコピー

相关推荐:

Python多线程中阻塞(join)与锁(Lock)使用误区解析

python多线程之事件Event的使用详解

以上がPythonのマルチスレッド、ロック、イベントの仕組みの簡単な使い方を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

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

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

定量通貨取引ソフトウェア 定量通貨取引ソフトウェア Mar 19, 2025 pm 04:06 PM

この記事では、3つの主要な交換、Binance、OKX、およびgate.ioの定量的取引機能を調査し、定量的トレーダーが適切なプラットフォームを選択できるようにすることを目指しています。この記事では、最初に定量的取引の概念、利点、課題を紹介し、APIサポート、データソース、バックテストツール、リスク制御機能など、優れた定量的取引ソフトウェアが持つべき機能を説明します。その後、3つの交換の定量的取引機能を比較し、詳細に分析し、それぞれその利点と短所を指摘し、最終的にさまざまなレベルの経験の定量的トレーダーにプラットフォーム選択の提案を提供し、リスク評価と戦略的バックテストの重要性を強調しました。 あなたが初心者であろうと経験豊富な定量的トレーダーであろうと、この記事はあなたに貴重なリファレンスを提供します

Pythonでコールを実装する方法-DeepseekPythonコールメソッドガイド Pythonでコールを実装する方法-DeepseekPythonコールメソッドガイド Mar 12, 2025 pm 12:51 PM

Deepseek Deep Learning Library Python Call Guide Deepseekは、さまざまなニューラルネットワークモデルの構築とトレーニングに使用できる強力なディープラーニングライブラリです。この記事では、Pythonを使用してDeepSeekを呼び出すためにDeep Learning Developmentを詳細に紹介します。 Python 1を使用してDeepseekを呼び出す手順。Python環境とPIPツールがインストールされていることを確認してください。次のコマンドを使用してDeepSeekをインストールします。PipinStallDeepSeek2をインポートします。

バイナンスアルファとは何ですか バイナンスアルファとは何ですか Mar 25, 2025 pm 03:39 PM

ANBI Alphaは、Binanceプラットフォームのプロのトレーダーや投資家向けのツールおよびサービス集約プラットフォームです。そのコア関数には、次のものが含まれます。1。戦略スクエアは、さまざまな取引戦略を結びつける。 2。カスタム取引戦略を許可する戦略ビルダー。 3.市場分析ツールを提供する高度なデータ分析。 4。専門的な投資家のニーズを満たすための機関レベルのサービス。

取引所を介してオプションヘッジ命令を送信できる交換 取引所を介してオプションヘッジ命令を送信できる交換 Mar 28, 2025 pm 03:27 PM

2024年の時点で、トレーディング端末を介してオプションヘッジングの指示を直接送信するサポートをサポートする主流の暗号通貨交換:1。デリビットは、デルタヘッジやガンマスカルピングなどの高度な戦略をサポートし、Webバージョン/APIワンクリックヘッジを提供します。 2。OKXは、ボラティリティヘッジと戦略の組み合わせツール、およびWeb/アプリに組み込みのヘッジパネルをサポートしています。 3. Binanceは保護ヘッジをサポートし、手動またはAPIの組み合わせ位置を必要とします。 4。CME、標準オプションを提供し、ブローカーを通じてアクセスを必要とする。 5。Ledgerx、専門レベルのヘッジツールを提供し、機関の認証を必要とします。

ランプアーキテクチャの下でnode.jsまたはPythonサービスを効率的に統合する方法は? ランプアーキテクチャの下でnode.jsまたはPythonサービスを効率的に統合する方法は? Apr 01, 2025 pm 02:48 PM

多くのウェブサイト開発者は、ランプアーキテクチャの下でnode.jsまたはPythonサービスを統合する問題に直面しています:既存のランプ(Linux Apache MySQL PHP)アーキテクチャWebサイトのニーズ...

ラテックスフォーミュラで多層ネストされた括弧を効率的に解析し、それらを多次元辞書に変換するにはどうすればよいですか? ラテックスフォーミュラで多層ネストされた括弧を効率的に解析し、それらを多次元辞書に変換するにはどうすればよいですか? Apr 01, 2025 am 08:57 AM

Pythonは、ラテックスマルチレイヤーブラケット:多次元辞書の多くのラテックスを構築します...

文字セットとレイヤー数に基づいて非反復的な順列の組み合わせを生成し、同じ組み合わせのすべての文字を除外する方法は? 文字セットとレイヤー数に基づいて非反復的な順列の組み合わせを生成し、同じ組み合わせのすべての文字を除外する方法は? Apr 01, 2025 am 06:57 AM

文字セットとレイヤー番号に基づいて、順列の組み合わせを生成します。この記事では、重複を避けるために、特定の文字セットとレイヤー番号に基づいて、対応する順列の組み合わせ結果を生成する方法を紹介します...

Scapy Crawlerを使用するときにパイプラインの永続的なストレージファイルを書き込めない理由は何ですか? Scapy Crawlerを使用するときにパイプラインの永続的なストレージファイルを書き込めない理由は何ですか? Apr 01, 2025 pm 04:03 PM

Scapy Crawlerを使用する場合、パイプラインの永続的なストレージファイルを書くことができない理由は?ディスカッションデータクローラーにScapy Crawlerを使用することを学ぶとき、あなたはしばしば...

See all articles