当前位置: 首页 > news >正文

python测试开发基础---线程和进程的概念

多线程和多进程

多线程和多进程是实现并发的两种主要方法,它们各有特点和适用场景。下面详细讲解它们的区别:

1. 基本定义

  • 多线程(Multithreading)

    • 在一个单一进程内创建多个线程,每个线程都可以独立执行任务。所有线程共享进程的内存和资源。

  • 多进程(Multiprocessing)

    • 创建多个独立的进程,每个进程有自己的内存空间和资源。进程之间相互独立,不共享内存。

2. 内存管理

  • 多线程

    • 所有线程共享同一进程的内存空间,包括数据和代码。这使得线程间的数据共享比较容易,但也带来了线程安全的问题。例如,多个线程同时修改共享数据时,可能会发生竞态条件或数据损坏。

  • 多进程

    • 每个进程拥有独立的内存空间,进程之间的数据不共享。进程间的通信(IPC,Inter-Process Communication)需要通过专门的机制,如管道、消息队列或共享内存。进程之间的隔离性较强,不会因为一个进程的崩溃而影响其他进程。

3. 开销和性能

  • 多线程

    • 创建和管理线程的开销较小,因为线程共享同一进程的资源。

    • 线程之间的上下文切换开销较小,但需要额外的同步机制(如锁)来确保线程安全。

  • 多进程

    • 创建和管理进程的开销较大,因为每个进程都有独立的内存空间和资源。

    • 进程间的上下文切换开销较大,但进程之间不需要同步机制,因为进程是隔离的。

4. 并发性

  • 多线程

    • 适合在同一进程中并发执行多个任务,这些任务通常需要频繁地共享数据。例如,网络服务器处理多个请求时,使用线程可以高效地管理并发任务。

    • 在 CPU 密集型任务中,由于全局解释器锁(GIL)的存在(在 Python 中),多线程的并发性能可能受到限制。

  • 多进程

    • 适合处理 CPU 密集型任务,因为每个进程可以独立运行在不同的 CPU 核心上,从而实现真正的并行处理。

    • 进程的创建和销毁较慢,但适合需要高度隔离和独立性任务的场景。

5. 错误处理

  • 多线程

    • 如果一个线程崩溃,可能会导致整个进程崩溃,因为线程共享同一进程的资源和内存。

  • 多进程

    • 如果一个进程崩溃,其他进程不会受到直接影响,因为进程是相互隔离的。

6. 适用场景

  • 多线程

    • 适用于 I/O 密集型任务,如网络请求、文件读写等,需要频繁进行 I/O 操作的场景。

    • 在 Python 中,由于 GIL 的限制,多线程在 CPU 密集型任务中的效果可能不如多进程。

  • 多进程

    • 适用于 CPU 密集型任务,如数据处理、计算密集型操作等,可以充分利用多核 CPU 的计算能力。

    • 适合需要进程隔离、资源独立的任务,如处理不同的服务或任务。

示例代码

多线程示例(Python):

import threading
import time
​
def worker():print('Thread starting')time.sleep(2)print('Thread ending')
​
threads = []
for _ in range(3):t = threading.Thread(target=worker)threads.append(t)t.start()
​
for t in threads:t.join()

多进程示例(Python):

import multiprocessing
import time
​
def worker():print('Process starting')time.sleep(2)print('Process ending')
​
processes = []
for _ in range(3):p = multiprocessing.Process(target=worker)processes.append(p)p.start()
​
for p in processes:p.join()

总结

  • 多线程:适合 I/O 密集型任务,线程共享内存和资源,开销较小,但需要注意线程安全。

  • 多进程:适合 CPU 密集型任务,进程间隔离性强,适合需要独立运行和较高容错性的场景,但创建和管理进程的开销较大。

在 Python 中,线程(thread)是用于并发执行代码的轻量级执行单元。Python 的线程支持由 threading 模块提供。线程使得程序能够同时运行多个任务,提高了程序的执行效率,特别是在处理 I/O 密集型操作时。以下是一些关于 Python 线程的基本概念和使用示例:

基本概念

  1. 线程创建:

    • 你可以通过继承 threading.Thread 类并重写其 run 方法来创建线程。

    • 也可以通过传递一个可调用对象(如函数)给 Thread 类的构造函数来创建线程。

  2. 线程同步:

    • 由于多个线程可以同时访问共享资源,需要使用线程同步机制(如锁)来避免数据竞争和不一致性。

    • threading.Lockthreading.RLockthreading.Condition 是常用的同步工具。

  3. 全局解释器锁 (GIL):

    • Python 的 CPython 实现使用 GIL,这意味着即使在多线程环境下,任何时刻只有一个线程在执行 Python 字节码。因此,多线程对 CPU 密集型操作的提升有限,但对 I/O 密集型操作有帮助。

示例代码

基本线程创建与使用
import threading
import time
​
def worker():"""线程执行的函数"""print(f"线程 {threading.current_thread().name} 正在工作")time.sleep(2)print(f"线程 {threading.current_thread().name} 工作完成")
​
# 创建线程
thread1 = threading.Thread(target=worker, name="Worker1")
thread2 = threading.Thread(target=worker, name="Worker2")
​
# 启动线程
thread1.start()
thread2.start()
​
# 等待线程结束
thread1.join()
thread2.join()
​
print("所有线程完成")
线程同步
import threading
​
# 创建一个锁对象
lock = threading.Lock()
​
def thread_safe_function():"""线程安全的函数"""with lock:print(f"线程 {threading.current_thread().name} 正在访问共享资源")# 模拟对共享资源的访问time.sleep(1)print(f"线程 {threading.current_thread().name} 完成对共享资源的访问")
​
# 创建多个线程
threads = []
for i in range(5):t = threading.Thread(target=thread_safe_function, name=f"Thread-{i}")t.start()threads.append(t)
​
# 等待所有线程完成
for t in threads:t.join()
​
print("所有线程完成")

常用线程工具

  • threading.Event: 用于线程间的事件通知。

  • threading.Condition: 用于在特定条件下让线程等待或通知其他线程。

  • threading.Semaphore: 控制同时访问某个资源的线程数量。

线程的使用要根据具体情况权衡性能和复杂度,尤其在涉及共享数据和资源时,需要谨慎处理同步问题。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 鸿蒙轻内核M核源码分析系列三 数据结构-任务排序链表
  • 【软件设计】常用设计模式--工厂模式
  • 经验笔记:DevOps
  • Linux 硬件学习 s3c2440 arm920t蜂鸣器
  • C语言深度剖析--不定期更新的第二弹
  • 基于视觉-语言模型的机器人任务规划:ViLaIn框架解析
  • Avalonia 动画和视觉效果详解
  • http、https、https原理
  • [详细建模已更新]2024数学建模国赛高教社杯A题:“板凳龙” 闹元宵 思路代码文章助攻手把手保姆级
  • Ubuntu上安装配置(jdk/tomcat/ufw防火墙/mysql)+mysql卸载
  • 2024国赛数学建模-模拟火算法(MATLAB 实现)
  • 【FreeRTOS】Tickless低功耗模式
  • iOS——方法交换Method Swizzing
  • 安防监控视频打手机检测算法核心技术打手机检测算法源码、模型简介
  • Centos安装配置Gitea(Ubuntu等系统也可参考)
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • Date型的使用
  • flask接收请求并推入栈
  • HTTP--网络协议分层,http历史(二)
  • Meteor的表单提交:Form
  • Node 版本管理
  • PermissionScope Swift4 兼容问题
  • ViewService——一种保证客户端与服务端同步的方法
  • 百度地图API标注+时间轴组件
  • 笨办法学C 练习34:动态数组
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 后端_ThinkPHP5
  • 使用SAX解析XML
  • 网页视频流m3u8/ts视频下载
  • 携程小程序初体验
  • ​低代码平台的核心价值与优势
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第1节 (全局数据、栈和堆)
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (编译到47%失败)to be deleted
  • (精确度,召回率,真阳性,假阳性)ACC、敏感性、特异性等 ROC指标
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (区间dp) (经典例题) 石子合并
  • *算法训练(leetcode)第四十五天 | 101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104. 建造最大岛屿
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .NET MAUI Sqlite数据库操作(二)异步初始化方法
  • .NET 解决重复提交问题
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .ui文件相关
  • :=
  • @RequestMapping处理请求异常
  • [000-01-030].Zookeeper学习大纲
  • [5] CUDA线程调用与存储器架构
  • [AHK] WinHttpRequest.5.1报错 0x80092004 找不到对象或属性
  • [BZOJ5250][九省联考2018]秘密袭击(DP)
  • [C/C++] -- 二叉树
  • [C][栈帧]详细讲解
  • [CentOs7]图形界面
  • [idea]关于idea开发乱码的配置
  • [iOS]Win8下iTunes无法连接iPhone版本的解决方法