この記事では主に Python のマルチスレッド、ロック、イベントの仕組みについて簡単に紹介しますので、参考にしてください。一緒に見てみましょう
スレッドとプロセス
threading.Thread
まず、スレッドを継承してスレッドを作成する例を見てみましょう。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.isAlive()
Python GIL (Global Interpreter Lock)
# 锁: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
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----")
スレッドロック(ミューテックス)
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 の違い:
Events
イベントオブジェクトは、スレッド間の通信を実現するためのシグナルの設定、シグナルのクリア、待機などを提供する単純なスレッド通信メカニズムを実装します。
event.set()
イベントオブジェクトのset()メソッドを使用した場合、isSet()メソッドはtrueを返す
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のマルチスレッド、ロック、イベントの仕組みの簡単な使い方を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。