多线程
多进程
-
进程是什么?
- 系统中正在运行的一个应用程序
-
它有什么特点?
- 1个CPU核心只能执行1个进程,其它进程就处于阻塞状态 。多个CPU核心就可以同时执行N个任务
多线程
-
线程是什么?
- 进程中包含的执行单元
-
它有什么特点?
- 1个进程可包含多个线程
- python 1次只能执行1个线程 因为线程锁(资源竞争问题)
-
为什么爬虫里面可以采用多线程?(有啥好处呢?)
它在一些场景比较适合它(能够优化程序 ) I/O 网络IO
如何创建线程 队列 锁的问题
创建线程
# 1 通过函数 向Thread方法传递类对象
# 小建议 凡是程序一上线程,那么复杂度就提升了,出BUG的效率也就提升了
import threading
import time
def demo():
print('hello 我是子线程')
if __name__ == '__main__':
for i in range(5):
t = threading.Thread(target=demo)
time.sleep(1)
t.start()
# 2 通过类 继承Thread父类,并改写run()方法
import threading
import time
class A(threading.Thread):
def run(self):
for i in range(5):
print('hello 我是子线程')
time.sleep(1)
if __name__ == '__main__':
a = A()
a.start()
# import time
# import threading
# # 主线程会等待子线程结束之后在结束
# def demo1():
# for i in range(5):
# print('hello everybody')
# time.sleep(1)
#
#
# if __name__ == '__main__':
# t = threading.Thread(target=demo1)
# t.setDaemon(True) # 守护线程
# t.start()
# # t.join() # 等待子线程执行结束之后我再执行
# print(1)
# print(type(t)) #<class 'threading.Thread'>
主线程和子线程的执行关系
- 主线程会等待子线程结束之后再结束
- join() 等待子线程结束之后,主线程继续执行
- setDaemon() 守护线程,不会等待子线程结束
查看线程数量
threading.enumerate() 查看当前线程的数量
验证子线程的执行与创建
当调用Thread的时候,不会创建线程。
当调用Thread创建出来的实例对象的start方法的时候,才会创建线程以及开始运行这个线程。
补充
守护线程
守护线程拥有自动结束自己生命周期的特性,而非守护线程不具备这个特点。
应用:
1、如果主线程是永远都不会结束的,那设置一个线程为守护线程是没必要的,设不设置都一样。
2、什么时候需要设置为守护线程?如果希望子线程一直运行(类似于后台运行),可以把子线程的代码写在while True里面一直循环,但同时要设置为守护线程,不然主线程结束了,子线程还一直运行,程序结束不了。
线程中主线程与子线程之间的关系
1、最常见的情况,主线程中开启了一个子线程,开启之后,主线程与子线程互不影响各自的生命周期,即主线程结束,子线程还可以继续执行;子线程结束,主线程也能继续执行。
2、主线程开启了子线程,但是主线程结束,子线程也随之结束
这里使用了Thread.setDaemon(true)方法
3、主线程开启了一个子线程,主线程必须要等子线程运行完之后,才能结束主线程
这里使用了join()方法,让主线程等待子线程结束,然后主线程继续执行。这里join()方法必须要在子线程启动之后,再调用。
本文介绍了进程和线程的概念,强调了多线程在I/O密集型任务如爬虫中的优势。在Python中,由于GIL限制,一次只能执行一个线程,但可以通过线程池或守护线程实现并发。线程的创建和执行有明确步骤,join()和setDaemon()方法用于控制线程生命周期。理解主线程与子线程的关系对于正确使用多线程至关重要。

被折叠的 条评论
为什么被折叠?



