线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。
基本使用
- 导包
- import threading
- 实例化 ,传入函数名,参数。参数为元组形式传递
- t = threading.Thread(target=func, args=(arg1, ))
- 开启线程 ,不能使用run方法,否则就只是普通的调用函数
- t.start()
- 线程等待,等待子线程结束、主线程再继续执行
- t.join()
- 守护线,主线程不会等待子线程结束
- t.setdaemon(True)
- 查看线程数量
- t.enumerate()
继承方式创建线程
import threadingclass Producer(threading.Thread):def __init__(self, num):super().__init__()self.num = numdef run(self):for i in range(self.num):print(f"producer {i}\n")class Consumer(threading.Thread):def __init__(self, num):super().__init__()self.num = numdef run(self):for i in range(self.num):print(f"consumer {i}\n")if __name__ == '__main__':p = Producer(5)c = Consumer(3)p.start()c.start()p.join()c.join()

- 参数传递需要初始化基类- 主线程不会等待子线程结束后再结束- 子线程在运行结束后会销毁- 不使用run方法开启线程,如果使用run方式只是普通的调用函数
线程间通信
- 线程之间可以共享全局变量,如下代码,如果数据正确最终num应该为2000001,但显然结果并不是。
import threadingnum = 1def func1():global numfor i in range(1000000):num += 1def func2():global numfor i in range(1000000):num += 1if __name__ == '__main__':t = threading.Thread(target=func1)t1 = threading.Thread(target=func2)t.start()t1.start()t.join()t1.join()print("num",num)

- 多线程对同一数据进行写操作时会造成紊乱,所以需要线程需要进行同步
线程锁
- 某个线程要更改共享数据时,先将其锁定,此时资源的状态为”锁定”,其他线程不能改变,只到该线程释放资源,将资源的状态变成”非锁定”,其他的线程才能再次锁定该资源。
- 互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。
- 方法
- mutex = threading.Lock()
- mutex.acquire()
- mutex.release()
import threadingnum = 1def func1(lock):global numfor i in range(1000000):lock.acquire()num += 1lock.release()def func2(lock):global numfor i in range(1000000):lock.acquire()num += 1lock.release()if __name__ == '__main__':# 创建线程锁lock = threading.Lock()t = threading.Thread(target=func1, args=(lock,))t1 = threading.Thread(target=func2, args=(lock,))t.start()t1.start()t.join()t1.join()print("num",num)

- 可见,对数据相同的数据操作上锁之后,这次的结果就是正确的了,保证了数据的准确性
队列(FIFO)
- from queue import Queue 导入
- q = Queue() 实例化
- 方法
- 本质区别
- 线程是任务调度和执行的最小单位
- 进程是程序资源调度单位,包含线程
- 包含关系
- 线程属于进程的一部分
- 进程可以拥有多个线程
- 内存开销
- 复制一份代码、资源创建子进程。进程之间拥有相互独立的内存控件,切换开销较大
- 线程共享资源,并且使用的是进程里的资源,切换开销较小
- 适用条件
- 线程适用于IO密集型操作,如爬虫
- 进程适用于计算密集型操作,如数据建模

