Python线程的创建、执行和管理以及注意事项

简介: Python提供了多种方法来创建、执行和管理线程,并且需要注意线程安全性和性能方面的问题。在选择方法时,需要考虑具体需求和场景。例如用”汽车”和“冰淇淋”作为关键词对B站进行搜索,将返回的视频标题进行采集整理并写入数据库,同时计算数据总量,以此进行热点事件分析

6565ng-2.jpeg

Python提供了多种方法来创建、执行和管理线程,并且需要注意线程安全性和性能方面的问题。其中使用threading模块创建线程,并获取其执行的函数返回值的方法有:

  1. 使用concurrent.futures模块:提供了高级API,可以将返回值和异常从工作线程传递到主线程。但可能比使用threading模块更耗费资源。
  2. 使用multiprocessing.pool模块:提供了类似的接口,可以使用进程或线程池,并使用apply_async方法异步地执行函数并获取结果。但需要序列化和传递数据,而且不能共享内存。
  3. 使用可变对象作为参数传递给线程的构造器,并让线程将其结果存储在该对象的指定位置。但可能会导致竞争条件。
  4. 使用Thread的子类:重写run和join方法,使得join方法可以返回目标函数的返回值。但需要访问一些私有的数据结构。

在选择方法时,需要考虑具体需求和场景。以下是需要注意的一些方面:

  1. concurrent.futures模块可以简化线程的创建和管理,但可能比使用threading模块更耗费资源。
  2. multiprocessing.pool模块可以利用多核处理器并行执行函数,但需要序列化和传递数据,而且不能共享内存。
  3. 使用可变对象作为参数传递给线程可能会导致竞争条件,即多个线程同时修改同一个对象,造成数据不一致或错误。
  4. 使用Thread的子类来返回目标函数的返回值可能会破坏Thread的原有设计,而且需要访问一些私有的数据结构。
  5. Python的线程受到全局解释器锁(GIL)的限制,即在任何时刻只有一个线程能够执行Python字节码,因此对于计算密集型的任务,线程并不能提高性能。
  6. Python的线程在执行I/O操作或其他阻塞调用时会释放GIL,因此对于I/O密集型的任务,线程可以提高性能。
  7. Python的线程需要注意线程安全性,即避免多个线程同时访问或修改共享的资源,否则可能会造成数据损坏或不一致。
  8. Python提供了一些工具来保证线程安全性,例如锁(Lock)、信号量(Semaphore)、定时器(Timer)和屏障(Barrier)等。

例如用”汽车”和“冰淇淋”作为关键词对B站进行搜索,将返回的视频标题进行采集整理并写入数据库,同时计算数据总量,以此进行热点事件分析,代码如下:

# 导入所需的模块importrequestsimportreimportsqlite3importthreading# 定义一个函数,根据关键词和页码获取B站搜索结果页面的HTML内容defget_html(keyword, page):
# 构造请求头和参数headers= {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"    }
params= {
"keyword": keyword,
"page": page,
"order": "totalrank"    }
#设置亿牛云爬虫代理加强版 代理IP的服务器地址、端口、用户名和密码proxyHost="www.16yun.cn"proxyPort="31111"# 代理验证信息proxyUser="16YUN"proxyPass="16IP"proxyMeta="http://%(user)s:%(pass)s@%(host)s:%(port)s"% {
"host" : proxyHost,
"port" : proxyPort,
"user" : proxyUser,
"pass" : proxyPass,
    }
# 设置 http和https访问都是用HTTP代理proxies= {
"http"  : proxyMeta,
"https" : proxyMeta,
    }
# 发送GET请求,获取响应内容,使用代理IP和用户名密码response=requests.get("https://search.bilibili.com/all", headers=headers, params=params, proxies=proxies)
# 返回HTML内容returnresponse.text# 定义一个函数,从HTML内容中提取视频标题,并将其写入数据库defextract_and_save(html):
# 连接数据库,创建游标conn=sqlite3.connect("bilibili.db")
cursor=conn.cursor()
# 创建数据表,如果已存在则忽略cursor.execute("CREATE TABLE IF NOT EXISTS videos (title TEXT)")
# 从HTML内容中提取视频标题,使用正则表达式匹配titles=re.findall(r"<a title=\"(.*?)\" href=", html)
# 遍历每个标题,将其插入数据表中fortitleintitles:
cursor.execute("INSERT INTO videos VALUES (?)", (title,))
# 提交事务,关闭连接conn.commit()
conn.close()
# 定义一个函数,计算数据库中的数据总量,并打印结果defcount_and_print():
# 连接数据库,创建游标conn=sqlite3.connect("bilibili.db")
cursor=conn.cursor()
# 查询数据表中的记录数cursor.execute("SELECT COUNT(*) FROM videos")
count=cursor.fetchone()[0]
# 打印结果print(f"共采集了{count}条数据")
# 关闭连接conn.close()
# 定义一个主函数,使用线程进行快速I/O操作defmain():
# 定义关键词和页码范围keyword="汽车 冰淇淋"pages=range(1, 11)
# 创建一个空列表,用于存储线程对象threads= []
# 遍历每个页码,创建一个线程对象,执行get_html和extract_and_save函数,并将其添加到列表中forpageinpages:
thread=threading.Thread(target=lambda: extract_and_save(get_html(keyword, page)))
thread.start()
threads.append(thread)
# 等待所有线程结束forthreadinthreads:
thread.join()
# 调用count_and_print函数,计算并打印数据总量count_and_print()
# 调用主函数if__name__=="__main__":
main()

总体来说,这段代码使用了多线程技术,使用多个线程并发地访问B站的搜索结果页面,提取其中的视频标题,并将其写入数据库,将网络请求和数据库操作分别放到不同的线程中执行,从而实现了快速爬取和处理大量数据的目的。同时,该代码还使用了爬虫代理IP,提高了爬虫的稳定性和安全性。

相关文章
|
2月前
|
数据采集 存储 JSON
Python爬取知乎评论:多线程与异步爬虫的性能优化
Python爬取知乎评论:多线程与异步爬虫的性能优化
|
2月前
|
人工智能 安全 调度
Python并发编程之线程同步详解
并发编程在Python中至关重要,线程同步确保多线程程序正确运行。本文详解线程同步机制,包括互斥锁、信号量、事件、条件变量和队列,探讨全局解释器锁(GIL)的影响及解决线程同步问题的最佳实践,如避免全局变量、使用线程安全数据结构、精细化锁的使用等。通过示例代码帮助开发者理解并提升多线程程序的性能与可靠性。
|
2月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
3月前
|
JSON 算法 Java
打造终端里的下载利器:Python实现可恢复式多线程下载器
在数字时代,大文件下载已成为日常需求。本文教你用Python打造专业级下载器,支持断点续传、多线程加速、速度限制等功能,显著提升终端下载体验。内容涵盖智能续传、多线程分块下载、限速控制及Rich库构建现代终端界面,助你从零构建高效下载工具。
191 1
|
2月前
|
数据采集 存储 Java
多线程Python爬虫:加速大规模学术文献采集
多线程Python爬虫:加速大规模学术文献采集
|
3月前
|
数据采集 网络协议 前端开发
Python多线程爬虫模板:从原理到实战的完整指南
多线程爬虫通过并发请求大幅提升数据采集效率,适用于大规模网页抓取。本文详解其原理与实现,涵盖任务队列、线程池、会话保持、异常处理、反爬对抗等核心技术,并提供可扩展的Python模板代码,助力高效稳定的数据采集实践。
141 0
|
8月前
|
并行计算 安全 Java
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
在Python开发中,GIL(全局解释器锁)一直备受关注。本文基于CPython解释器,探讨GIL的技术本质及其对程序性能的影响。GIL确保同一时刻只有一个线程执行代码,以保护内存管理的安全性,但也限制了多线程并行计算的效率。文章分析了GIL的必要性、局限性,并介绍了多进程、异步编程等替代方案。尽管Python 3.13计划移除GIL,但该特性至少要到2028年才会默认禁用,因此理解GIL仍至关重要。
537 16
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
|
11月前
|
安全 数据处理 开发者
Python中的多线程编程:从入门到精通
本文将深入探讨Python中的多线程编程,包括其基本原理、应用场景、实现方法以及常见问题和解决方案。通过本文的学习,读者将对Python多线程编程有一个全面的认识,能够在实际项目中灵活运用。
|
7月前
|
Python
python3多线程中使用线程睡眠
本文详细介绍了Python3多线程编程中使用线程睡眠的基本方法和应用场景。通过 `time.sleep()`函数,可以使线程暂停执行一段指定的时间,从而控制线程的执行节奏。通过实际示例演示了如何在多线程中使用线程睡眠来实现计数器和下载器功能。希望本文能帮助您更好地理解和应用Python多线程编程,提高程序的并发能力和执行效率。
198 20

热门文章

最新文章

推荐镜像

更多