threading 装饰器的实现
创作背景
-
最近,本菜鸡找到了一个 网站 ,用来追番呀,下载动漫,电影之类的,但有的动漫没有提供下载功能,所以只能 自己下载了呀😏 (dddd)
-
目前 demo 已经做出来了,但还没有封装完成,还有诸多想实现的功能还没有实现
-
这个是我嫌 下载动漫 的时候速度慢,想开多线程进行 下载 ,但遇到了一些小问题(因为 我很菜,不会多线程),现在算是解决了,写篇博客以供参考
实现过程
target
- 我想在 进行关键字搜索 的时候使用多线程,然后可以同时搜索多个关键字
实现(部分代码,未修复 bug)
- 为了说明主要问题,我只粘贴了 部分代码
import requests
import threading
class download_dytt_videos():
def __init__(self, kw_list):
self.kw_list = kw_list
self.headers = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0'
}
self.lock = threading.Lock()
def _threading(self, func, **kwargs):
t = threading.Thread(target = func, kwargs = kwargs)
t.start()
t.join()
def search(self):
'''
本函数用来搜索关键词,并由用户选择要下载的视频
:param kw: 要搜索的关键词
:return: 选择后的视频的简介页的链接
'''
for kw in self.kw_list:
@self._threading
def kw_search():
... # 代码细节
text = requests.get(
url=url,
headers=self.headers
).text
... # 代码细节
出现的问题(已解决)
1. 线程锁问题
- 如下
ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。 urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, '远程主机强迫关闭了一个现有的连接。', None, 10054, None))
- 这个问题出现是因为 线程同步的时候,多个线程同时访问同一数据时,会出现冲突
- 我这里的问题是 get 请求时加入 hreaders,都使用的 self.hreaders,没有加锁的时候,发生冲突
- 解决方案:使用线程锁,在进行多线程搜索,进行 get 请求前后 分别加入获得锁和释放锁 ,代码如下(在函数 search 中修改)
# 获得锁
self.lock.acquire()
text = requests.get(
url=url,
headers=self.headers
).text
# 释放锁,让其他进程使用
self.lock.release()
- 注:不能在函数 _threading 中加入获得锁和释放锁 ,因为那样就和不加锁一样了,线程同时运行时就会同时要求获得锁,也会产生冲突
2. 装饰器传参问题
- 我本想 通过装饰器给开启多线程的函数进行传参,比如说,这样的
def _threading(self, func, kw, **kwargs)
- 但因为自己学的装饰器没有学牢固,一直报错 缺少参数
- 所以最后使用的上边代码的装饰器
- 后来我又尝试了一下,可以实现了
- 代码如下
def _threading(self, **kwargs):
def f_threading(func):
t = threading.Thread(target = func, kwargs = kwargs)
t.start()
t.join()
return f_threading
def search(self):
for kw in self.kw_list:
@self._threading(keyword = kw)
def kw_search(keyword):
- 但这样有点麻烦了,因为是在循环中,所以这个函数内的函数 可以直接使用 kw,反正这 都是在函数 search 的内部实现的,外部也调用不了 kw_search 这个函数
- 意义: 虽然装饰器传参在我这里没有很大的作用,但这也是一种用法,在其他地方有用处,各位可以自己找一下适用的场景,练练手
总结
- 两个知识点,threading 和 python 装饰器
- 各位可以自己尝试一下,有什么问题可以给我留言(●’◡’●)
结尾
以上就是我要分享的内容,因为学识尚浅,会有不足,还请各位大佬指正。
有什么问题也可在评论区留言。