From: https://www.cnblogs.com/jokerbj/p/7460260.html

一 threading模块介绍

multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍

官网链接:https://docs.python.org/3/library/threading.html?highlight=threading#

二 开启线程的两种方式

方式一
方式二

三 在一个进程下开启多个线程与在一个进程下开启多个子进程的区别

1 谁的开启速度快
2 瞅一瞅pid
3 同一进程内的线程共享该进程的数据?

四 练习

练习一:

多线程并发的socket服务端
客户端

练习二:三个任务,一个接收用户输入,一个将用户输入的内容格式化成大写,一个将格式化后的结果存入文件

View Code

五 线程相关的其他方法

Thread实例对象的方法# isAlive(): 返回线程是否活动的。# getName(): 返回线程名。# setName(): 设置线程名。threading模块提供的一些方法:# threading.currentThread(): 返回当前的线程变量。# threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。# threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

View Code

主线程等待子线程结束

from threading import Thread
import time
def sayhi(name):time.sleep(2)print('%s say hello' %name)if __name__ == '__main__':t=Thread(target=sayhi,args=('egon',))t.start()t.join()print('主线程')print(t.is_alive())'''egon say hello主线程False'''

六 守护线程

无论是进程还是线程,都遵循:守护xxx会等待主xxx运行完毕后被销毁

需要强调的是:运行完毕并非终止运行

#1.对主进程来说,运行完毕指的是主进程代码运行完毕#2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕

详细解释:

#1 主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束,#2 主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。

from threading import Thread
import time
def sayhi(name):time.sleep(2)print('%s say hello' %name)if __name__ == '__main__':t=Thread(target=sayhi,args=('egon',))t.setDaemon(True) #必须在t.start()之前设置t.start()print('主线程')print(t.is_alive())'''主线程True'''

迷惑人的例子

七 全局解释器锁GIL介绍

'''
定义:
In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple
native threads from executing Python bytecodes at once. This lock is necessary mainly
because CPython’s memory management is not thread-safe. (However, since the GIL
exists, other features have grown to depend on the guarantees that it enforces.)
'''
结论:在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势

首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL

这篇文章透彻的剖析了GIL对python多线程的影响,强烈推荐看一下:http://www.dabeaz.com/python/UnderstandingGIL.pdf

回到顶部

7.1 GIL介绍

GIL本质就是一把互斥锁,既然是互斥锁,所有互斥锁的本质都一样,都是将并发运行变成串行,以此来控制同一时间内共享数据只能被一个任务所修改,进而保证数据安全。

可以肯定的一点是:保护不同的数据的安全,就应该加不同的锁。

要想了解GIL,首先确定一点:每次执行python程序,都会产生一个独立的进程。例如python test.py,python aaa.py,python bbb.py会产生3个不同的python进程

验证python test.py只会产生一个进程

在一个python的进程内,不仅有test.py的主线程或者由该主线程开启的其他线程,还有解释器开启的垃圾回收等解释器级别的线程,总之,所有线程都运行在这一个进程内,毫无疑问

#1 所有数据都是共享的,这其中,代码作为一种数据也是被所有线程共享的(test.py的所有代码以及Cpython解释器的所有代码)
例如:test.py定义一个函数work(代码内容如下图),在进程内所有线程都能访问到work的代码,于是我们可以开启三个线程然后target都指向该代码,能访问到意味着就是可以执行。#2 所有线程的任务,都需要将任务的代码当做参数传给解释器的代码去执行,即所有的线程要想运行自己的任务,首先需要解决的是能够访问到解释器的代码。

综上:

如果多个线程的target=work,那么执行流程是

多个线程先访问到解释器的代码,即拿到执行权限,然后将target的代码交给解释器的代码去执行

解释器的代码是所有线程共享的,所以垃圾回收线程也可能访问到解释器的代码而去执行,这就导致了一个问题:对于同一个数据100,可能线程1执行x=100的同时,而垃圾回收执行的是回收100的操作,解决这种问题没有什么高明的方法,就是加锁处理,如下图的GIL,保证python解释器同一时间只能执行一个任务的代码

7.2 GIL与Lock

GIL保护的是解释器级的数据,保护用户自己的数据则需要自己加锁处理,如下图

7.3 GIL与多线程

有了GIL的存在,同一时刻同一进程中只有一个线程被执行

听到这里,有的同学立马质问:进程可以利用多核,但是开销大,而python的多线程开销小,但却无法利用多核优势,也就是说python没用了,php才是最牛逼的语言?

别着急啊,老娘还没讲完呢。

要解决这个问题,我们需要在几个点上达成一致:

#1. cpu到底是用来做计算的,还是用来做I/O的?#2. 多cpu,意味着可以有多个核并行完成计算,所以多核提升的是计算性能#3. 每个cpu一旦遇到I/O阻塞,仍然需要等待,所以多核对I/O操作没什么用处 

一个工人相当于cpu,此时计算相当于工人在干活,I/O阻塞相当于为工人干活提供所需原材料的过程,工人干活的过程中如果没有原材料了,则工人干活的过程需要停止,直到等待原材料的到来。

如果你的工厂干的大多数任务都要有准备原材料的过程(I/O密集型),那么你有再多的工人,意义也不大,还不如一个人,在等材料的过程中让工人去干别的活,

反过来讲,如果你的工厂原材料都齐全,那当然是工人越多,效率越高

结论:

  对计算来说,cpu越多越好,但是对于I/O来说,再多的cpu也没用

  当然对运行一个程序来说,随着cpu的增多执行效率肯定会有所提高(不管提高幅度多大,总会有所提高),这是因为一个程序基本上不会是纯计算或者纯I/O,所以我们只能相对的去看一个程序到底是计算密集型还是I/O密集型,从而进一步分析python的多线程到底有无用武之地

#分析:
我们有四个任务需要处理,处理方式肯定是要玩出并发的效果,解决方案可以是:
方案一:开启四个进程
方案二:一个进程下,开启四个线程#单核情况下,分析结果: 如果四个任务是计算密集型,没有多核来并行计算,方案一徒增了创建进程的开销,方案二胜如果四个任务是I/O密集型,方案一创建进程的开销大,且进程的切换速度远不如线程,方案二胜#多核情况下,分析结果:如果四个任务是计算密集型,多核意味着并行计算,在python中一个进程中同一时刻只有一个线程执行用不上多核,方案一胜如果四个任务是I/O密集型,再多的核也解决不了I/O问题,方案二胜#结论:现在的计算机基本上都是多核,python对于计算密集型的任务开多线程的效率并不能带来多大性能上的提升,甚至不如串行(没有大量切换),但是,对于IO密集型的任务效率还是有显著提升的。

转载于:https://www.cnblogs.com/Raul2018/p/9515766.html

python开发线程:线程守护线程全局解释器锁相关推荐

  1. Python进阶并发基础--线程,全局解释器锁GIL由来,如何更好的利用Python线程,

    全局解释器锁GIL 官方对于线程的介绍: 在 CPython 中,由于存在全局解释器锁,同一时刻只有一个线程可以执行 Python代码(虽然某些性能导向的库可能会去除此限制).如果你想让你的应用更好地 ...

  2. 【Python爬虫学习笔记11】Queue线程安全队列和GIL全局解释器锁

    Queue线程安全队列 在Python多线程编程中,虽然threading模块为我们提供了Lock类和Condition类借助锁机制来处理线程并发执行,但在实际开发中使用加锁和释放锁仍是一个经常性的且 ...

  3. python-生产者消费者模型_线程_线程互斥锁_GIL全局解释器锁

    进程 1. 开启进程的两种方式 2. 进程对象其他属性和方法-pid: 进程id号 os.getpid()-ppid: 父进程id号 os.getppid() -is_alive(): 当前进程是否存 ...

  4. 线程与全局解释器锁(GIL)

    一.线程概论 1.何为线程 每个进程有一个地址空间,而且默认就有一个控制线程.如果把一个进程比喻为一个车间的工作过程那么线程就是车间里的一个一个流水线. 进程只是用来把资源集中到一起(进程只是一个资源 ...

  5. 线程之全局解释器锁加一些了解知识点

    ---恢复内容开始--- 1.GIL全局解释器锁 2.GIL与普通的互斥锁 3.死锁 4.信号量 5.event事件 6.线程q队列 7.补充 基于TCP使用线程实现高并发 一.GIL全局解释器锁 G ...

  6. 十六、python开发之进程与线程

    一.程序与进程: 1.概念:  程序并不能单独运行,必须系统为它分配资源,装载到内存中才能运行,而这执行的过程就是进程 程序是指令的集合,是进程运行的静态描述文件 进程是程序的一次执行活动,是动态的过 ...

  7. python守护线程_Python守护线程用法实例

    本文实例讲述了Python守护线程用法.分享给大家供大家参考,具体如下: 如果你设置一个线程为守护线程,就表示你在说这个线程是不重要的,在进程退出的时候,不用等待这个线程退出.如果你的主线程在退出的时 ...

  8. python开两个守护线程_python 守护线程

    守护线程 如果python线程是守护线程,那么以为着这个线程是"不重要"的,"不重要"意味着如果他的父进程结束了但该守护线程没有运行完,守护进程就会被强制结束. ...

  9. JAVA守护线程 非守护线程

    笔记: 第一篇转载写的比较好,将守护线程同linux的守护进程概念进行了对比. 当非守护线程执行完jvm就退出,不管是否还有守护线程在执行.所以守护线程尽量不要执行逻辑代码,顶多执行一些可有可无的辅助 ...

最新文章

  1. Android p2p service,android – WifiP2pDnsSdServiceInfo.newInstance中的可用服务类型
  2. 重载输入cin和输出cout运算符
  3. python【数据结构与算法】分治算法之大整数乘法
  4. UA SIE545 优化理论基础0 优化建模7 二值变量的应用
  5. 清华计算机系媒体所,清华大学计算机系媒体所《时光机》新年联欢会小结
  6. python(matplotlib4)——Scatter 散点图,Bar柱状图(方向:向上,向下),柱状图添加注释
  7. dederss.php美国与,Dede经验:全站rss/连载和分类首页模板替换
  8. 怎么看待苹果公司要求分成微信、知乎打赏32%?
  9. linux 取消分区,如何在 Linux 中删除分区 | Linux 中国
  10. Ubuntu下逻辑坏道解决方案
  11. close 和 shutdown 的差别
  12. UCI机器学习数据库的Python API介绍
  13. Getshell总结
  14. map_server
  15. 51单片机的新手入门前所有疑问整理
  16. 如何撰写数据运营分析报告
  17. 【四足机器人--摆动相足端位置速度轨迹规划】(4.1)FootSwingTrajectory(bezier曲线计算脚的摆动轨迹)代码解析
  18. 程序员高薪“盛宴”背后:人才结构性过剩和缺失共存
  19. ds6708 symbol 驱动_SymbolDS6708
  20. 一个月面试4家,3家Offer,来看看面霸真君如何面试的

热门文章

  1. 思科发力虚拟化和云服务 推出多款新品
  2. 趋势科技:黑客勒索瞄准智能电视
  3. The Text Splitting (将字符串分成若干份,每份长度为p或q)
  4. django-admin 设计User外键,设计model
  5. 开源 免费 java CMS - FreeCMS-功能说明-用户管理
  6. 关于:为什么在 Real Producer 10 Plus 里面找不到 RealAudio 10 with aacPlus的解答
  7. [力扣] 501. 二叉搜索树中的众数
  8. Python3 AttributeError: module 'cv2' has no attribute 'SIFT'
  9. C++中相对路径和绝对路径
  10. 什么是拉电流和灌电流?