1.认识GIL:

说到GIL一直是代码专家们一直以来想要解决的问题,也是被许多程序员诟病的,下面带领大家看下官方threading模块document中如何去描述对于GIL这个全局解释器锁的:https://docs.python.org/3/library/threading.html

全局解释器锁

所使用的机制的CPython解释器来确保只有一个线程执行的Python 字节码在一个时间。通过使对象模型(包括关键的内置类型,例如dict)隐式安全地防止并发访问,从而简化了CPython的实现。锁定整个解释器可以使解释器更容易进行多线程处理,但会牺牲多处理器机器提供的许多并行性。

但是,某些扩展模块(标准的或第三方的)被设计为在执行诸如压缩或散列之类的计算密集型任务时释放GIL。另外,在执行I / O时,始终释放GIL。

过去创建“自由线程”解释器(一种以更精细的粒度锁定共享数据的解释器)的努力并未成功,因为在常见的单处理器情况下性能会受到影响。相信克服该性能问题将使实施更加复杂,因此维护成本更高。

在这里专门对全局解释器锁的概念引入时说了这么一段话,第一指明了GIL造成了python解释器一次只有一个线程可以获取解释器锁,也就是解释器本身是自带锁的,谁先拿到谁就可以抢占到cpu的资源,

从而导致了python无论一个线程怎么去跑,都只能最多跑满一个cpu核心,就造成了多核cpu资源的无法利用的带来的资源浪费,但是这是否就意味着python一无是处呢,答案肯定No!,虽然GIL对于cpu密集的支持

不是那么的友好,但是,对于IO密集的支持恰恰是其他语言所无法比拟的,就拿asyncio这这个协程库来讲:https://docs.python.org/3/library/asyncio.html

1.第一部分认识多线程创建以及调用,上一节我讲解了源码关于多线程实现方式有两种:第一种通过Thread类传入可调用target对象,第二种继承Thread类并重写run方法:

下面就以target进行举例:

可以看到线程的资源抢占效果;证明GIL锁的的确真实存在的;

先在我们如果更换t.join()到t1.start()的后面会发现,线程每次不管怎么运行都是先执行完threading1线程,再去执行threading2线程,而这完全得益于joIn()函数:

我们来看源码是怎么解释join()的:

等待直到线程终止。这将阻塞调用线程,直到join()被调用方法的线程终止(正常或通过未处理的异常终止),或者直到发生可选的超时。

讲完join():

我们再来认识一个有趣的参数daemon->守护线程:

先看源码:

daemon用'来指示线程是否是守护线程,必须在线程start()方法调用之前设置,否则会引发RunTimeError,当不存在活动的非守护线程时将退出python程序

演示daemon:

正常默认daemon为False:

可以看到主线程运行结束后退出后子线程继续运行并输出了内容,

但是现在如果有个需求要求我们实现主线程退出后必须kill掉子线程那么,如何实现这个需求,这就用到了daemon,我们只需要设置为True:

主线程运行结束后并没有等待子线程

运行完毕就kill掉了子线程没有输出finsh打印就已经结束了子线程了

# 多线程实现方式二,继承Thread 类,重写run方法:

这是一种很基本的写法。实际开发过程我们会涉及到类的调用以及类的方法引用写法会发生改变:

这里实现了在线程外部定义一个类,其中类的方法test作为一个可调用对象传给了继承了Thread并重写run方法的MyCallable类,这里留一个思考题,对于以上重写run你会发现我们的run是无法实现结果回调的

这就意味着,我们需要根据实际场景使用不同的模块处理不同的需求,可以给大家一个小提示可以使用concurrent.futures或者使用  queue.Queue()来实现结果回调,因为在queue源码中,它是基于deque来实现的而deque是线程安全的也就意味queue也是线程安全的,有兴趣的可以自己去看下

j结语:

python threading2种调用方式实例的更多相关文章

  1. Python包模块化调用方式详解

    Python包模块化调用方式详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一般来说,编程语言中,库.包.模块是同一种概念,是代码组织方式. Python中只有一种模块对象类型 ...

  2. 【转】SVG与HTML、JavaScript的三种调用方式

    原文:https://www.cnblogs.com/guohu/p/5085045.html SVG与HTML.JavaScript的三种调用方式 一.在HTMl中访问SVG的DOM 1 2 3 4 ...

  3. 【转载】Redis的Java客户端Jedis的八种调用方式(事务、管道、分布式…)介绍

    转载地址:http://blog.csdn.net/truong/article/details/46711045 关键字:Redis的Java客户端Jedis的八种调用方式(事务.管道.分布式…)介 ...

  4. 同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式

    1. 概念理解        在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:   同步/异步主要针对C端: 同步:    ...

  5. python 线程的调用方式

    python 线程的调用方式 #!/usr/bin/env python #-*- coding:utf-8 -*- # author:leo # datetime:2019/5/24 9:44 # ...

  6. Javascript中函数的四种调用方式

    一.Javascript中函数的几个基本知识点: 1.函数的名字只是一个指向函数的指针,所以即使在不同的执行环境,即不同对象调用这个函数,这个函数指向的仍然是同一个函数. 2.函数中有两个特殊的内部属 ...

  7. 浅谈js函数三种定义方式 & 四种调用方式 & 调用顺序

    在Javascript定义一个函数一般有如下三种方式: 函数关键字(function)语句: function fnMethodName(x){alert(x);} 函数字面量(Function Li ...

  8. Vue组件的三种调用方式

    最近在写fj-service-system的时候,遇到了一些问题.那就是我有些组件,比如Dialog.Message这样的组件,是引入三方组件库,比如element-ui这样的,还是自己实现一个?虽然 ...

  9. magento 列表页显示产品属性值的几种调用方式

    之前有人提到要在列表显示一些特定的属性,除了自带的名字,价格等.因为列表页和产品页都有一个同名的产品对象:$_product,而在产品页,$_product是直接可以用$_product->ge ...

随机推荐

  1. 使用Gradle推送SpringBoot项目源码到私有仓库

    应用场景: 在SpringCloud微服务项目中,通常会划分成多个业务服务,而这些服务之间一般会使用Feign组件进行相互调用,所以在项目开发中会衍生出一个问题:Feign客户端代码该由服务调用方的开 ...

  2. <packaging>pom</packaging>是什么意思

    <packaging>pom</packaging>是什么意思? 答: 以下配置<packaging>pom</packaging>的意思是使用mave ...

  3. go 环境及4开发

    国内加速 在gopath目录执行 go env -w GOPROXY=direct go env -w GOSUMDB=off go env -w GOPROXY=https://goproxy.io ...

  4. idea将普通项目转换为maven项目

    方式一 1.在项目根目录下,新建文件 pom.xml,并填写好内容. 2.在pom.xml文件上,右键 Add as Maven Project 或 在项目上,右键 Add Framework Sup ...

  5. LCT[Link-Cut-Tree学习笔记]

    部分摘抄于 FlashHu candy99 所以文章篇幅较长 请有足够的耐心(不是 其实不用学好splay再学LCT的-/kk (至少现在我平衡树靠fhq) 如果学splay的话- 也许我菜吧-LCT ...

  6. Gin框架之文件上传

    一.单文件上传 前端代码 <!DOCTYPE html> <html lang="zh-CN"> <head> <title>上传文 ...

  7. Page Object设计模式(二)——poium测试库

    一.简介 poium是一个基于Selenium/appium的Page Object测试库,最大的特点是简化了Page层元素的定义. 项目地址:https://github.com/SeldomQA/ ...

  8. 20200228 尚硅谷-NIO

    尚硅谷-NIO Java NIO简介 Java NIO(New IO.Non Blocking IO)是从Java1.4版本开始引入的新的 IO API,可以替代标准的 Java IO API. NI ...

  9. 12 : API

    Object 概念 所有类的顶级父类 存在于java.lang包中,这个包不需要我们手动导包 常用方法 toString() 默认返回   类名@地址  的格式,来展示对象的地址值,如:a00000. ...

  10. 对象浅拷贝Object.assign

    const target = { a: { b: { c: { d: 1 } }, e: 5, f: 6, h: 10 } } const source = { a: { b: { c: { d: 1 ...