01.线程
1.1 什么是线程
- 1)线程是操作系统调度的最小单位
- 2)线程是进程正真的执行者,是一些指令的集合(进程资源的拥有者)
- 3)同一个进程下的多个
线程共享内存空间
,数据直接访问(数据共享) - 4)为了保证数据安全,必须使用
线程锁
说明:
下面利用for循环同时启动50个线程并行执行,执行时间是3秒而不是所有线程执行时间的总和
1 | import threading |
1.2 GIL锁和线程锁
- GIL全局解释器锁
- 在python全局解释器下,保证同一时间只有一个线程运行。
- 防止多个线程都修改数据
- 线程锁(互斥锁)
- GIL锁只能保证同一时间只能有一个线程对某个资源操作,但当上一个线程还未执行完毕时可能就会释放GIL,其他线程就可以操作了
- 线程锁本质把线程中的数据加了一把互斥锁
- 加上线程锁之后所有其他线程,读都不能读这个数据
- 有了GIL全局解释器锁为什么还需要线程锁
- 因为cpu是分时使用的
在有GIL的情况下执行 count = count + 1 会出错原因解析,用线程锁解决方法
1 | # 1)第一步:count = 0 count初始值为0 |
死锁定义
- 两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去
1.3 多线程或者线程池
- 线程有哪些模块?
- 线程池有哪些模块?
1.4 join()和setDaemon()
2.4.1 join()
实现所有线程都执行结束后再执行主线程
1 | import threading |
2.4.2 setDaemon()
守护线程,主线程退出时,需要子线程随主线程退出
1 | import threading |
1.5 Python中使用过的线程模块?
1.5.1 threading
- Python提供了几个用于多线程编程的模块,包括thread、threading和Queue等。
- thread和threading模块允许程序员创建和管理线程。
1 | import threading |
1.5.2 concurrent.futures
-
1、简介
参考官网- 1、Python标准库为我们提供了threading和multiprocessing模块编写相应的多线程/多进程代码
- 2、但是当项目达到一定的规模,频繁创建/销毁进程或者线程是非常消耗资源的,这个时候我们就要编写自己的线程池/进程池,以空间换时间。
- 3、但从Python3.2开始,标准库为我们提供了concurrent.futures模块,它提供了ThreadPoolExecutor和ProcessPoolExecutor两个类,
- 4、实现了对threading和multiprocessing的进一步抽象,对编写线程池/进程池提供了直接的支持。
-
2、Executor和Future
-
1. Executor
-
concurrent.futures模块的基础是Exectuor,Executor是一个抽象类,它不能被直接使用。
-
但是它提供的两个子类ThreadPoolExecutor和ProcessPoolExecutor却是非常有用
-
我们可以将相应的tasks直接放入线程池/进程池,不需要维护Queue来操心死锁的问题,线程池/进程池会自动帮我们调度。
-
-
2. Future
- Future你可以把它理解为一个在未来完成的操作,这是异步编程的基础,
- 传统编程模式下比如我们操作queue.get的时候,在等待返回结果之前会产生阻塞,cpu不能让出来做其他事情
- 而Future的引入帮助我们在等待的这段时间可以完成其他的操作。
-
-
concurrent.futures.ThreadPoolExecutor 抓取网页
1 | import requests |
__END__