python — 线程 & 线程池
一、线程
(一) 使用
Python中使用线程有两种方式:函数或者用类来包装线程对象。
1. 方式一:函数
-
用法:
函数式:调用 _thread 模块中的函数来产生新线程。语法如下:
# 创建线程 t = threading.Thread(target, args, kwargs) # 启动线程 t.start()
- 参数说明:
- target - 线程函数,传递函数名称。
- args - 传递给线程函数的参数,必须是个tuple类型。
- kwargs - 可选参数。
- 参数说明:
-
示例:
import threading import time def say_hello(who, age): while True: print("%s is %s years old !" % (who, age)) time.sleep(3) if __name__ == "__main__": # 创建线程 t = threading.Thread(target=say_hello, args=('cm', 25)) t.start()
2. 方式二:线程对象
-
用法:
线程对象,使用 threading 模块创建线程,可以通过直接从 threading.Thread 继承创建一个新的子类,并实例化后调用 start() 方法启动新线程,即它调用了线程的 run() 方法。
-
示例:
import threading import time class thread_iml(threading.Thread): def __init__(self): pass def run(self) -> None: while True: print('hello') time.sleep(5) if __name__ == "__main__": mythread = thread_iml() mythread.start()
-
Thread类提供了以下方法:
- run():用以表示线程活动的方法。
- start():启动线程活动。
- join([time]):等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。(正常情况下,相当于执行完当前线程再执行其他线程)
- isAlive(): 返回线程是否活动的。
- getName(): 返回线程名。
- setName(): 设置线程名。
二、线程池
-
pip命令:
pip install threadpool
三、线程安全
- 参考资料:https://blog.csdn.net/weixin_43790276/article/details/91069959
(一) 实现方式
1. 同步机制
-
方式1:互斥锁
使用
互斥锁
来实现同步,避免资源竞争问题发生mutex = threading.Lock() # 获得锁 mutex.acquire() # 操作数据 do something... # 释放锁 mutex.release()
-
示例代码:
from threading import Thread, Lock num = 0 def add_num(): global num for i in range(3000000): # 获得锁 mutex.acquire() num += 1 num -= 1 # 释放锁 mutex.release() if __name__ == '__main__': t1 = Thread(target=add_num) t2 = Thread(target=add_num) t3 = Thread(target=add_num) t1.start() t2.start() t3.start() print(num)
-
优化:
可以在获得锁的时候加上超时时间,解决存在多个锁时候,产生的死锁问题
result = mutex.acquire(timeout=10)
-