1.什么的是线程
在程序里一个执行路线就叫做线程,线程是程序执行的最小单位

2.多线程的优点

  • 使用线程可以把占据长时间的程序中的任务放到后台去处理。
  • 在处理I/O密集程序的运行速度可能加快(ps:计算型密集任务除外)
  • 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。
  • 线程可以被抢占(中断)。
  • .在其他线程正在运行时,线程可以暂时搁置(也称为睡眠) – 这就是线程的退让

3.多线程的缺点

  • 无法使用多核,由于gil锁的存在,他只能一个一个的取抢锁
  • 多线程对I/O 有效果,对于需要cpu计算的时候,反复切换会浪费时间反而会降低效率
  • 同时操作同一个共享资源,所以造成了资源破坏,即线程不安全

总结:

  1. Python 多线程并发,可以提高 i/o 密集型程序的运行效率,但对于计算密集型程序, Python

  2. 多线程并发并不能显著提升效率(并非是不适合使用,因为鬼知道现实世界会有什么样的应用场景)

4.python实现简单的多线程

Python3 通过两个标准库 _thread 和 threading 提供对线程的支持,由于_thread只是为了兼容python2的thread模块,所以推荐使用threading模块实现多线程。
threading提供了如下方法:

  • run(): 用以表示线程活动的方法。
  • start():启动线程活动。
  • join([time]): 等待到线程中止。
  • isAlive(): 返回线程是否活动的。
  • getName(): 返回线程名。
  • setName(): 设置线程名。
#导入线程模块
import threading
#导入时间模块
import time#唱歌
def singing():for i in range(1,21):print("我会唱歌~~~ %d" %i)time.sleep(0.5)#跳舞
def dancing():for i in range(1,21):print("我会跳舞^^^ %d" %i)time.sleep(0.5)#打篮球
def play_basketball():for i in range(1,21):print("我还会打篮球··· %d" %i)time.sleep(0.5)#练习
def practise():for i in range(1,21):print("我是来自美国,练习时长两年半的练习生$$$ %d" %i)time.sleep(0.5)def main():"""创建启动线程"""t_singing = threading.Thread(target=singing)t_dancing = threading.Thread(target=dancing)t_play_basketball = threading.Thread(target=play_basketball)t_practise = threading.Thread(target=practise)t_singing.start()t_dancing.start()t_play_basketball.start()t_practise.start()if __name__ == '__main__':main()

结果:

我是来自美国,练习时长两年半的练习生$$$ 1
我会唱歌~~~ 2我会跳舞^^^ 2我是来自美国,练习时长两年半的练习生$$$ 2
我还会打篮球··· 2
我会唱歌~~~ 3
我会跳舞^^^ 3
我还会打篮球··· 3
我是来自美国,练习时长两年半的练习生$$$ 3
我会唱歌~~~ 4
我会跳舞^^^ 4
我还会打篮球··· 4
我是来自美国,练习时长两年半的练习生$$$ 4
我会跳舞^^^ 5
我会唱歌~~~ 5
我是来自美国,练习时长两年半的练习生$$$ 5

5.GIL(Global Interpreter Lock)全局解释器锁

在非python环境中,单核情况下,同时只能有一个任务执行。多核时可以支持多个线程同时执行。但是在python中,无论有多少核,同时只能执行一个线程。究其原因,这就是由于GIL的存在导致的。

GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定。某个线程想要执行,必须先拿到GIL,我们可以把GIL看作是“通行证”,并且在一个python进程中,GIL只有一个。拿不到通行证的线程,就不允许进入CPU执行。GIL只在cpython中才有,因为cpython调用的是c语言的原生线程,所以他不能直接操作cpu,只能利用GIL保证同一时间只能有一个线程拿到数据。而在pypy和jpython中是没有GIL的。

6.Python多线程的工作过程:

python在使用多线程的时候,调用的是c语言的原生线程。

  • 拿到公共数据
  • 申请gil
  • python解释器调用os原生线程
  • os操作cpu执行运算
  • 当该线程执行时间到后,无论运算是否已经执行完,gil都被要求释放
  • 进而由其他进程重复上面的过程
  • 等其他进程执行完后,又会切换到之前的线程(从他记录的上下文继续执行),整个过程是每个线程执行自己的运算,当执行时间到就进行切换(context
    switch)。

简述:

线程锁的意义
当多个线程同时修改同一条数据时可能会出现脏数据,所以,出现了线程锁,即同一时刻允许一个线程执行操作。
也就是为了解决线程不安全问题

死锁和递归锁
什么是死锁:就是两个线程都等待对方释放资源。

案例:

#死锁
from threading import Thread,Lock
import time
mutexA = Lock()
mutexB = Lock()class Work(Thread):def run(self):self.f1()self.f2()def f1(self):mutexA.acquire()print('%s 拿到了A锁 ' % self.name)mutexB.acquire()print('%s拿到了B锁' % self.name)mutexB.release()print('%s 释放了 B锁' % self.name)mutexA.release()print('%s 释放了 A锁' % self.name)def f2(self):mutexB.acquire()time.sleep(2)print('%s 拿到了B锁 ' % self.name)mutexA.acquire()print('%s拿到了A锁' % self.name)mutexA.release()print('%s 释放了 A锁' % self.name)mutexB.release()print('%s 释放了 B锁' % self.name)if __name__ == '__main__':for i in range(5):t = Work()t.start()

结果:
Thread-1 拿到了A锁
Thread-1拿到了B锁
Thread-1 释放了 B锁
Thread-1 释放了 A锁
Thread-2 拿到了A锁
Thread-1 拿到了B锁

递归锁
递归锁:Rlock

Rlock内部有一个count 初始为0 ,锁一下加1,释放了就减1

 #递归锁
from threading import Thread,RLock
import time
mutexA = mutexB = RLock()
class Work(Thread):def run(self):self.f1()self.f2()def f1(self):mutexA.acquire()print('%s 拿到了A锁 ' % self.name)mutexB.acquire()print('%s拿到了B锁' % self.name)mutexB.release()print('%s 释放了 b锁' % self.name)mutexA.release()print('%s 释放了 a锁' % self.name)def f2(self):mutexB.acquire()time.sleep(2)print('%s 拿到了A锁 ' % self.name)mutexA.acquire()print('%s拿到了B锁' % self.name)mutexA.release()print('%s 释放了 b锁' % self.name)mutexB.release()print('%s 释放了 a锁' % self.name)if __name__ == '__main__':for i in range(3):t = Work()t.start()

结果:

Thread-1 拿到了A锁
Thread-1拿到了B锁
Thread-1 释放了 b锁
Thread-1 释放了 a锁
Thread-1 拿到了A锁
Thread-1拿到了B锁
Thread-1 释放了 b锁
Thread-1 释放了 a锁
Thread-2 拿到了A锁
Thread-2拿到了B锁
Thread-2 释放了 b锁
Thread-2 释放了 a锁
Thread-2 拿到了A锁
Thread-2拿到了B锁
Thread-2 释放了 b锁
Thread-2 释放了 a锁
Thread-3 拿到了A锁
Thread-3拿到了B锁
Thread-3 释放了 b锁
Thread-3 释放了 a锁
Thread-3 拿到了A锁
Thread-3拿到了B锁
Thread-3 释放了 b锁
Thread-3 释放了 a锁

python中的多线程 GIL(全局解释器锁) 死锁与递归锁相关推荐

  1. gil php,网络编程之多线程——GIL全局解释器锁

    网络编程之多线程--GIL全局解释器锁 一.引子 定义: In CPython, the global interpreter lock, or GIL, is a mutex that preven ...

  2. 多线程—— GIL(全局解释器锁)

    文章目录 1.前言 2.测试 GIL 1.前言 python 的多线程 threading 有时候并不是特别理想. 最主要的原因是就是, Python 的设计上, 有一个必要的环节, 就是 Globa ...

  3. Python中的GIL(全局解释器锁)

    1. GIL全称Global Interpreter Lock,每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行代码. 2.GIL的缺点 GIL使Python不能充分利用多核心 ...

  4. python GIL :全局解释器

    cpython 解释器中存在一个GIL(全局解释器锁),无论多少个线程.多少颗cpu 他的作用就是保证同一时刻只有一个线程可以执行代码,因此造成了我们使用多线程的时候无法实现并行. 因为有GIL的存在 ...

  5. Python之路 34:并发与并行、锁(GIL、同步锁、死锁与递归锁)、信号量、线程队列、生消模型、进程(基础使用、进程通信、进程池、回调函数)、协程

    内容: 同步锁 死锁.递归锁 信号量和同步对象(暂时了解即可) 队列------生产者和消费者模型 进程(基础使用.进程通信.进程池.回调函数) 协程 一.并发并行与同步异步的概念 1.1.并发和并行 ...

  6. android 线程互斥锁,线程锁(互斥锁Mutex)及递归锁

    一.线程锁(互斥锁) 在一个程序内,主进程可以启动很多个线程,这些线程都可以访问主进程的内存空间,在Python中虽然有了GIL,同一时间只有一个线程在运行,可是这些线程的调度都归系统,操作系统有自身 ...

  7. 互斥锁、死锁、递归锁、信号量、Event

    互斥锁 死锁和递归锁 Semaphore信号量 Event事件 互斥锁 互斥锁也叫用户锁.同步锁. 在多进程/多线程程序中,当多个线程处理一个公共数据时,会有数据安全问题,唯一能保证数据安全的,就是通 ...

  8. python gil 解除_详解Python中的GIL(全局解释器锁)详解及解决GIL的几种方案

    先看一道GIL面试题: 描述Python GIL的概念, 以及它对python多线程的影响?编写一个多线程抓取网页的程序,并阐明多线程抓取程序是否可比单线程性能有提升,并解释原因. GIL:又叫全局解 ...

  9. python多线程为啥是假的?(GIL 全局解释器锁)(python多线程不适合并行化的计算密集型代码)

    1. 问: 答: 2. from threading import Thread ​ def loop(): ​while True: ​print("亲爱的,我错了,我能吃饭了吗?&quo ...

最新文章

  1. java并行安全吗_并发和并行有什么区别
  2. CodeBlocks主题和字体
  3. 网络推广方法带你了解优质的网站结构对网站SEO有什么好处?
  4. Hadoop的安装(单机和集群)
  5. 为Pdf批量添加水印
  6. 20位大佬组团“踢馆”,谁超越了图灵?
  7. linux-基本权限UGO-读写执行权限
  8. 使用Docker启动Kafka-Manager
  9. Bootstrap进度条堆叠
  10. 程序员除了编代码,还能做哪些职业规划?
  11. 【Python】Python中文编码
  12. web.xml中配置启动时加载的servlet,load-on-starup
  13. 注册ActiveX控件时DllRegisterServer调用失败的解决方法
  14. Datawhale组队学习周报(第030周)
  15. 我走进了微缩的“物联国”
  16. 330tsl是什么意思_19款探岳330tsl两区豪华型怎么样?
  17. 微信用户提现功能 显示NO_AUTH | 产品权限验证失败,请查看您当前是否具有该产品的权限(企业付款到零钱 银行卡)
  18. 创建进程-CreateProcess (一)
  19. AM335x SPL(一)
  20. Camera AF和FF

热门文章

  1. getchar 和 getch区别
  2. 2021-04-28-飞机大战-001-day5-游戏滚动背景
  3. 说话中的引题技巧,及电影刘三姐中的歌词汇总
  4. 解决vs2013+wdk7 编译nt系统wdm驱动 error C2220: 警告被视为错误 - 没有生成“object”文件
  5. Android 发布代码到github 并且部署到 JitPack maven 仓库详细步骤
  6. 使用java.awt.Robot实现java版的自动点击事件
  7. Java程序设计——随机点名器
  8. 这些好用的跨境电商插件,你都听说几个?
  9. 2021河南科技大学计算机考研科目,2021河南科技大学考研参考书目
  10. IoC容器和 Dependency Injection模式 Inversion of Control Containers and the Dependency Injection pattern