`

python多进程和多线程的区别

阅读更多
多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了。

来看看多个线程同时操作一个变量怎么把内容给改乱了


import time, threading

# 假定这是你的银行存款:
balance = 0

def change_it(n):
    # 先存后取,结果应该为0:
    global balance
    balance = balance + n
    balance = balance - n

def run_thread(n):
    for i in range(100000):
        change_it(n)

t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
print(balance)

我们定义了一个共享变量balance,初始值为0,并且启动两个线程,先存后取,理论上结果应该为0,但是,由于线程的调度是由操作系统决定的,当t1、t2交替执行时,只要循环次数足够多,balance的结果就不一定是0了。
究其原因,是因为修改balance需要多条语句,而执行这几条语句时,线程可能中断,从而导致多个线程把同一个对象的内容改乱了。

两个线程同时一存一取,就可能导致余额不对,你肯定不希望你的银行存款莫名其妙地变成了负数,所以,我们必须确保一个线程在修改balance的时候,别的线程一定不能改。

如果我们要确保balance计算正确,就要给change_it()上一把锁,当某个线程开始执行change_it()时,我们说,该线程因为获得了锁,因此其他线程不能同时执行change_it(),只能等待,直到锁被释放后,获得该锁以后才能改。由于锁只有一个,无论多少线程,同一时刻最多只有一个线程持有该锁,所以,不会造成修改的冲突。创建一个锁就是通过threading.Lock()来实现
import time, threading

# 假定这是你的银行存款:
balance = 0
lock=threading.Lock()
def change_it(n):
    # 先存后取,结果应该为0:
    global balance
    balance = balance + n
    balance = balance - n

def run_thread(n):
    for i in range(50000):
        #获取锁
        lock.acquire()
        try:
            change_it(n)
        finally:
            lock.release()
           
       
t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
print(balance)
当多个线程同时执行lock.acquire()时,只有一个线程能成功地获取锁,然后继续执行代码,其他线程就继续等待直到获得锁为止。

获得锁的线程用完后一定要释放锁,否则那些苦苦等待锁的线程将永远等待下去,成为死线程。所以我们用try...finally来确保锁一定会被释放。


因为Python的线程虽然是真正的线程,但解释器执行代码时,有一个GIL锁:Global Interpreter Lock,任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核。

GIL是Python解释器设计的历史遗留问题,通常我们用的解释器是官方实现的CPython,要真正利用多核,除非重写一个不带GIL的解释器。

所以,在Python中,可以使用多线程,但不要指望能有效利用多核。如果一定要通过多线程利用多核,那只能通过C扩展来实现,不过这样就失去了Python简单易用的特点。

不过,也不用过于担心,Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。

小结

多线程编程,模型复杂,容易发生冲突,必须用锁加以隔离,同时,又要小心死锁的发生。

Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核。多线程的并发在Python中就是一个美丽的梦。

参考源码

multi_threading.py

do_lock.py

感觉本站内容不错,读后有收获?

我要小额赞助,鼓励作者写出更好的教程

还可以分享给朋友




多进程ThreadLocal
评论

发表评论

Sign In to Make a Comment

2.7旧版教程

锁的好处就是确保了某段关键代码只能由一个线程从头到尾完整地执行,坏处当然也很多,首先是阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了。其次,由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁,导致多个线程全部挂起,既不能执行,也无法结束,只能靠操作系统强制终止。
分享到:
评论

相关推荐

    python利用多进程、多线程实现网络数据下载(百度地图api中规划路径数据)

    使用python的多进程、多线程技术,实现互联网数据的并行下载,一个进程可以设置n个线程,多进程通过开启多个运行脚本来实现,这样可以根据具体的硬件环境任意启动多个进程。数据主要是通过下载百度地图api中

    Python语言多进程与多线程设计探究.pdf

    Python语言多进程与多线程设计探究.pdf

    Python-多进程与多线程.pdf

    ### Python多进程与多线程知识点详解 #### 一、多进程 ##### 1.... 在Python中,`multiprocessing`模块提供了...以上是关于Python多进程和多线程编程的核心知识点,理解和掌握这些知识点对于编写并发程序是非常重要的。

    TensorRT python多进程推理踩坑(csdn)————程序.pdf

    在使用TensorRT进行深度学习推理时,特别是在Python环境中,可能会遇到多线程或多进程的优化问题。本篇文章主要探讨了在TensorRT中实现多线程推理以及如何在Python的multiprocessing库下正确运行多进程推理的注意...

    完整版 Python高级开发课程 高级教程 08 Python多线程 多进程开发.pptx

    在Python高级开发中,多线程和多进程是两个重要的概念,它们被广泛应用于提高程序的并发性能,尤其是在处理大量数据或需要同时执行多个任务时。本课程将深入讲解这两个主题,帮助开发者提升Python应用程序的效率。 ...

    python selenium chrome 多开 多线程

    本主题聚焦于如何使用Python的Selenium与Chrome浏览器进行多开和多线程操作,结合phantomjs和chromedriver这两个关键组件来实现。首先,让我们详细了解一下这些概念。 1. **Selenium**: Selenium是一个强大的Web...

    python3多进程多线程协程IO多路复用等

    对python并发进行的笔记整理,个人所学习使用,主要包括多进程,多线程,协程,IO多路复用,进程线程通信等

    Python-Python3爬虫系列的理论验证比较同步依序下载多进程并发多线程并发和asyncio异步编程之间的效率差别

    本主题将深入探讨Python3中四种不同的并发模型:同步依序下载、多进程(multiprocessing)、多线程(multithreading)以及asyncio异步编程,并通过理论分析和实际案例对比它们之间的效率差异。 1. 同步依序下载: ...

    python 单线程多线程和多进程的比较

    在Python编程中,单线程、多线程和多进程是三种不同的并发执行方式,每种方式都有其独特的特点和适用场景。以下是对这些概念的详细解析: **单线程**: 在单线程编程中,程序的执行是顺序进行的,同一时间只能做一...

    Python 多进程、多线程效率对比

    Python 界有条不成文的准则: 计算密集型任务适合多进程,IO 密集型任务适合多线程。本篇来作个比较。 通常来说多线程相对于多进程有优势,因为创建一个进程开销比较大,然而因为在 python 中有 GIL 这把大锁的存在...

    python多进程和opencv图像处理的应用

    将Python多进程与OpenCV结合,我们可以实现大规模图像数据的并行处理。例如,在图像分类、目标检测或图像增强的任务中,我们可能需要对大量的图片进行预处理。通过创建多个进程,每进程负责处理一部分图像,可以显著...

    Python语言多进程与多线程设计探究.zip

    在Python编程中,多进程(Multiprocessing)和多线程(Multithreading)是两种并发执行的方式,它们允许程序在同一时间处理多个任务,提高程序的效率和响应速度。本资料"Python语言多进程与多线程设计探究"深入探讨...

    浅析Python多线程与多进程的使用

    本篇文章将深入探讨Python中的多线程和多进程概念,以及它们在实际应用中的优缺点。 首先,我们要理解“线程”和“进程”的基本概念。线程是程序执行的最小单位,一个进程中可以有多个线程,它们共享同一份内存空间...

    Python多进程并发与多线程并发编程实例总结

    Python多进程并发与多线程并发编程实例总结深入探讨了Python中多进程和多线程的并发编程技术,这些技术允许程序同时执行多个任务,以提高效率和响应速度。以下是知识点的总结: 1. 并发编程概念: - 并发编程是让...

    基于Python实现多进程的发送邮件.zip

    总的来说,这个课程设计涵盖了Python的多进程编程以及邮件发送的实践,这对于理解并发处理和实际应用中的通信问题非常有帮助。通过学习这个项目,开发者可以掌握如何在Python中有效地并行处理任务,以及如何利用SMTP...

    Python多线程与多进程笔记1

    Python 多线程和多进程是 Python 编程中两个重要的概念,它们分别对应着不同的并发编程模型。在本文中,我们将详细介绍 Python 中的多线程和多进程,并对比它们的异同。 多进程 多进程是指在一个程序中创建多个...

    PYthon-multithreading-Test.rar_python_python 多线程_python多线程_多线程

    本压缩包“PYthon-multithreading-Test.rar”包含了有关Python多线程测试的源码,旨在帮助用户深入理解和实践Python的线程操作。 Python中的多线程是通过`threading`模块实现的,这个模块提供了基本的线程和同步...

    Python多线程和多进程.docx

    Python多线程和多进程

    基于Python+PyQt制作GUI的劲爆多进程和多线程下载器

    【作品名称】:基于Python+PyQt制作GUI的劲爆多进程和多线程下载器 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】: ...

    Python 爬虫进阶:多线程与多进程实现策略

    本文将详细介绍如何在 Python 中实现爬虫的多线程和多进程,以提高爬取效率。 在 Python 中实现爬虫的多线程或多进程可以显著提高爬取效率,但同时也需要注意它们各自的适用场景和潜在问题。本文提供了多线程、多...

Global site tag (gtag.js) - Google Analytics