Python - 多线程
基本使用
"""
线程的基本使用:
sub_thread = threading.Thread(target=xxx)
xxx: 线程任务
"""
import threading
def singe():
"""任务一"""
for v in range(5):
print('正在唱歌。。。。')
def dance():
"""任务二"""
for v in range(5):
print('正在跳舞。。。')
if __name__ == '__main__':
# 创建线程类,指定多线成任务
# 注意指定的函数没有括号
thread_singe = threading.Thread(target=singe)
thread_dance = threading.Thread(target=dance)
# 启动多线程
thread_singe.start()
thread_dance.start()
获得线程数量和当前线程名称
"""
threading.current_thread() : 获得当前活跃的名称
threading.enumerate(): 返回当前活跃线程数
"""
import threading
import time
def singe():
"""任务一"""
for v in range(5):
print(f'{threading.current_thread()} 正在唱歌。。。。')
time.sleep(0.2)
def dance():
for v in range(5):
print(f'{threading.current_thread()}正在跳舞。。。')
time.sleep(0.2)
if __name__ == '__main__':
# 创建线程类,指定多线成任务
# 注意指定的函数没有括号
thread_singe = threading.Thread(target=singe)
thread_dance = threading.Thread(target=dance)
# 启动多线程
thread_singe.start()
thread_dance.start()
while True:
thread_list = threading.enumerate() # 返回当前活跃的线程列表
thread_num = len(thread_list) # 活跃线程数量
print(f'当前活跃的线程数量为{thread_num}')
if thread_num == 1:
break
time.sleep(0.2)
多线程函数传参
import threading
def singe(a, b, c):
"""任务一"""
print(f'a={a}, b={b}, c={c} ')
for v in range(5):
print('正在唱歌。。。。')
if __name__ == '__main__':
# 传参方式一:
# thread_singe = threading.Thread(target=singe, args=(10, 20, 30))
# 传参方式二:
# thread_singe = threading.Thread(target=singe, kwargs={'a': '10', 'b': '20', 'c': '30'})
# 传参方式三:
thread_singe = threading.Thread(target=singe, args=(10,), kwargs={'c': '20', 'b': '30'})
# 启动多线程
thread_singe.start()
守护线程(后台线程)
主线程退出后,子线程也要同时退出。设置方式
t.daemon = True 或者 t = threading.Thread(target=work1, daemon=True)
,默认是False,也就是主线程结束后,子线程依然在执行
作用:
如果有一个线程必须设置为无限循环,那么该线程不结束,意味着整个python程序就不能结束,那为了能够让python程序正常退出,将这类无限循环的线程设置为守护线程,当程序当中仅仅剩下守护线程时,python程序就能够正常退出,不必关心这类线程是否执行完毕。典型的守护线程GC 垃圾收集器
import threading
import time
def work1():
for x in range(10):
print('work1.......')
time.sleep(0.5)
if __name__ == '__main__':
t = threading.Thread(target=work1, daemon=True)
# t.daemon = True 也可以设置守护线程
t.start()
time.sleep(3)
print('主线程结束....')
exit()
自定义线程类
并发:当前任务数大于CPU核心数
并行:当前任务数小于等于CPU核心数
"""
1. 继承threading.Thread 类
2. 重写父类的run方法
3. 调用start方法启动子线程
"""
import threading
import time
class MyThread(threading.Thread):
def run(self) -> None:
for tmp in range(5):
print(f'sub thread{self.name} run....')
time.sleep(0.5)
if __name__ == '__main__':
my_thread = MyThread()
my_thread.start()
print(threading.current_thread().name)
互斥锁
import threading
import time
num = 0
"""
1.创建互斥锁: lock = threading.Lock(),注意需要放在创建线程之前
2.lock.acquire(): 请求锁
3.lock.release(): 释放锁
"""
def work1():
global num
for _ in range(1000000):
lock.acquire()
num += 1
lock.release()
print(f'{threading.current_thread().name} num is {num}')
def work2():
global num
for _ in range(1000000):
lock.acquire()
num += 1
lock.release()
print(f'{threading.current_thread().name} num is {num}')
if __name__ == '__main__':
lock = threading.Lock()
t1 = threading.Thread(target=work1)
t2 = threading.Thread(target=work2)
t1.start()
t2.start()
# 确保子线程执行完毕,才执行主线程
while len(threading.enumerate()) != 1:
time.sleep(1)
print(f'{threading.current_thread().name} num is {num}')
# out:
"""
Thread-1 (work1) num is 1720405
Thread-2 (work2) num is 2000000
MainThread num is 2000000
"""
本文来自博客园,作者:chuangzhou,转载请注明原文链接:https://www.cnblogs.com/czzz/p/15824124.html