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,提高了爬虫的稳定性和安全性。

相关文章
|
8天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
18天前
|
算法 数据处理 Python
Python并发编程:解密异步IO与多线程
本文将深入探讨Python中的并发编程技术,重点介绍异步IO和多线程两种常见的并发模型。通过对比它们的特点、适用场景和实现方式,帮助读者更好地理解并发编程的核心概念,并掌握在不同场景下选择合适的并发模型的方法。
|
1月前
|
并行计算 安全 Unix
Python教程第8章 | 线程与进程
本章主要讲解了线程与进程的概念,多线程的运用以及Python进程的相关案例学习
36 0
|
1月前
|
分布式计算 并行计算 Java
浅析Python自带的线程池和进程池
浅析Python自带的线程池和进程池
79 0
|
26天前
|
安全 Python
Python中的并发编程:多线程与多进程技术探究
本文将深入探讨Python中的并发编程技术,重点介绍多线程和多进程两种并发处理方式的原理、应用场景及优缺点,并结合实例分析如何在Python中实现并发编程,以提高程序的性能和效率。
|
1月前
|
数据采集 存储 Java
「多线程大杀器」Python并发编程利器:ThreadPoolExecutor,让你一次性轻松开启多个线程,秒杀大量任务!
「多线程大杀器」Python并发编程利器:ThreadPoolExecutor,让你一次性轻松开启多个线程,秒杀大量任务!
|
1月前
|
安全 调度 Python
Python中如何实现多线程?请举例说明。
Python中如何实现多线程?请举例说明。
14 0
|
1月前
|
Java 调度 Python
深入解析 Python asyncio 库:如何使用线程池实现高效异步编程
深入解析 Python asyncio 库:如何使用线程池实现高效异步编程
45 0
|
1月前
|
Python
Python中的并发编程与多线程
在当今高并发的网络应用环境中,如何充分利用计算资源来提高程序的执行效率是一个关键问题。本文将探讨Python中的并发编程技术,重点介绍了多线程的使用方法和注意事项,帮助读者更好地理解并发编程在Python中的应用。
|
2天前
|
调度 Python
Python多线程、多进程与协程面试题解析
【4月更文挑战第14天】Python并发编程涉及多线程、多进程和协程。面试中,对这些概念的理解和应用是评估候选人的重要标准。本文介绍了它们的基础知识、常见问题和应对策略。多线程在同一进程中并发执行,多进程通过进程间通信实现并发,协程则使用`asyncio`进行轻量级线程控制。面试常遇到的问题包括并发并行混淆、GIL影响多线程性能、进程间通信不当和协程异步IO理解不清。要掌握并发模型,需明确其适用场景,理解GIL、进程间通信和协程调度机制。
17 0

热门文章

最新文章