一、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.)

无论你启动多少个线程,Python解释器在同一时刻,都只允许一个线程在cpu上执行,Python启动一个线程是调用C语言的接口,让操作系统启动线程,所以所有的线程调度是操作系统在执行,而Python解释器在启动线程后只能等待操作系统返回结果。所以Python解释器为了防止同一时刻多个线程操作同一个数据,造成数据混乱,所以在cpython解释器中,加入了global interpreter lock。

注意:Jpython、pypy等解释器都没有GIL

二、Python中的多线程

- python 中的多线程虽然不能并行,但是能达到高并发的效果。并不是一无用处

2.1 threading模块
import threading
import time def run(i): #定义每个线程要运行的函数 print("线程::%s 正在运行" %i) time.sleep(1) if __name__ == '__main__': #注意args参数必须为元组格式,如只有一个参数后面要加括号
t1 = threading.Thread(target= run, args=(1, )) #生成一个线程实例 参数还有name 线程名,daemon 是否守护线程 True
t2 = threading.Thread(target= run, args=(2, )) #生成另一个线程实例 t1.start() #启动线程
t2.start() #启动另一个线程 print(t1.getName()) #获取线程名
print(t2.getName())
2.2 Join及守护线程

当你在启动一个线程之后,前面说过由于是调用系统创建,所以主进程就和创建的线程没有关系了。想象一下如果主进程的执行依赖于线程返回的结果,可是线程执行需要一定时间,当主进程 done 了,线程还没结束。
那就有问题了。所以这个时候 join 的左右就出来了,某个线程实例执行 join 方法,主进程会等到该线程执行完毕再从 join 后开始执行

如:我们生产10个线程。主线程同时等待所以线程执行完毕

def run(i):
print('线程 {} 在运行'.format(i))
time.sleep(1)
if i%2:
print('子线程done....') thread_list = []
for i in range(10):
t = threading.Thread(target= run, args(i, ))
t.start()
thread_list.append(t) for t in thread_list:
t.join() print('main thread done....') #执行结果为
线程 0 在运行
线程 1 在运行
线程 2 在运行
线程 3 在运行
线程 4 在运行
线程 5 在运行
线程 6 在运行
线程 7 在运行
线程 8 在运行
线程 9 在运行
子线程done....
子线程done....
子线程done....
子线程done....
子线程done....
main thread done.... #如果不使用join 的话 ,结果为...
线程 0 在运行
线程 1 在运行
线程 2 在运行
线程 3 在运行
线程 4 在运行
线程 5 在运行
线程 6 在运行
线程 7 在运行
线程 8 在运行
线程 9 在运行
main thread done....
子线程done....
子线程done....
子线程done....
子线程done....
子线程done....

在这儿我们可以看到,就算没有加 join 主进程还是等待子线程全部执行结束后才结束,但是中间执行类容不会等待,这是因为Python 自动在程序结尾处自动添加了 join

2.3 守护线程

设想一个列子:一个奴隶主创建了很多奴隶,奴隶主就是主进程,奴隶们是子线程,奴隶主只需要告诉奴隶们命令,他们就会去工作。奴隶主在创建奴隶们的时候,就给他们心脏上安了一个东西,告诉他们,只要我死了,不管你们当时在干嘛,这个东西就会工作,立刻杀死你们。意思就是主进程一旦结束,所有被设置为守护进程的子线程全部结束

而在threading 模块中,这个安装到奴隶(子线程,守护进程)的东西就是 daemon = True.

有两种方式实现,一是实例化一个线程时:

t = threading.Thread(target= fun, args= ( para , ), daemon= True)

第二种为:必须在线程执行前设置,一旦start 后设置,就会报错

def run(i):
print('线程 {} 在运行'.format(i))
time.sleep(1.5)
print('子线程done....') for i in range(2):
t = threading.Thread(target= run, args= (i, ))
t.setDaemon(True) #必须在线程执行前设置
t.start() print('main thread done....') #运行结果为 线程 0 在运行
线程 1 在运行
main thread done....

从最后的运行结果中可以看到,主进程并没有等着子线程执行完,就结束了!这就是 非守护线程, 守护进程的关系

线程锁(互斥锁)、递归锁 点击这儿

threading模块,python下的多线程的更多相关文章

  1. threading模块—Python多线程编程

    Threading 模块 threading 模块除了提供基本的线程和锁定支持外,还提供了更高级别.功能更全面的线程管理.threading 模块支持守护线程,其工作方式是:守护线程一般是一个等待客户 ...

  2. Python多线程(threading模块)

    线程(thread)是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. ...

  3. Python 浅析线程(threading模块)和进程(process)

    线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务 进程与线程 什么 ...

  4. 学会使用Python的threading模块、掌握并发编程基础

    threading模块 Python中提供了threading模块来实现线程并发编程,官方文档如下: 官方文档 添加子线程 实例化Thread类 使用该方式新增子线程任务是比较常见的,也是推荐使用的. ...

  5. python多进程与多线程编程

    进程(process)和线程(thread)是非常抽象的概念.多线程与多进程编程对于代码的并发执行,提升代码运行效率和缩短运行时间至关重要.下面介绍一下python的multiprocess和thre ...

  6. Python多进程与多线程编程及GIL详解

    介绍如何使用python的multiprocess和threading模块进行多线程和多进程编程. Python的多进程编程与multiprocess模块 python的多进程编程主要依靠multip ...

  7. python爬虫之多线程、多进程+代码示例

    python爬虫之多线程.多进程 使用多进程.多线程编写爬虫的代码能有效的提高爬虫爬取目标网站的效率. 一.什么是进程和线程 引用廖雪峰的官方网站关于进程和线程的讲解: 进程:对于操作系统来说,一个任 ...

  8. Python多进程和多线程是鸡肋嘛?【转】

    GIL是什么 Python的代码执行由 Python虚拟机(也叫解释器主循环,CPython版本)来控制,Python在设计之初就考虑到在解释器的主循环中,同时只有一个线程在运行.即每个CPU在任意时 ...

  9. Python:使用threading模块实现多线程编程

    转:http://blog.csdn.net/bravezhe/article/details/8585437 Python:使用threading模块实现多线程编程一[综述] Python这门解释性 ...

随机推荐

  1. 数据挖掘---Matplotib的学习

    什么是matplotlib mat - matrix 矩阵                二维数据 - 二维图表            plot - 画图            lib - libra ...

  2. windows下安装consul

    Consul 是一个支持多数据中心分布式高可用的服务发现和配置共享的服务软件, 由 HashiCorp 公司用 Go 语言开发, 基于 Mozilla Public License 2.0 的协议进行 ...

  3. Pycharm用鼠标滚轮控制字体大小

    一.pycharm字体放大的设置 File —> setting —> Keymap —>在搜寻框中输入:increase —> Increase Font Size(双击) ...

  4. ubuntu下安裝sogou拼音

    方法/步骤 打开搜狗输入法Linux版的官网http://pinyin.sogou.com/linux/?r=pinyin,并下载你需要的版本,这里选择64位版. 在Ubuntu14.01下可以直接点 ...

  5. 关于this的理解

    var o = { a:10, b:{ a:12, fn:function(){ console.log(this.a); //undefined console.log(this); //windo ...

  6. Loj #3057. 「HNOI2019」校园旅行

    Loj #3057. 「HNOI2019」校园旅行 某学校的每个建筑都有一个独特的编号.一天你在校园里无聊,决定在校园内随意地漫步. 你已经在校园里呆过一段时间,对校园内每个建筑的编号非常熟悉,于是你 ...

  7. jar包内的文件导出的注意点

    1.截取文件名 windows 和linux 通用 String fp[] = filePath.replaceAll("\\\\","/").split(&q ...

  8. [2] TensorFlow 向前传播算法(forward-propagation)与反向传播算法(back-propagation)

    TensorFlow Playground http://playground.tensorflow.org 帮助更好的理解,游乐场Playground可以实现可视化训练过程的工具 TensorFlo ...

  9. 05 python 初学(列表)

    列表,有点像c++里的数组 # _author: lily # _date: 2018/12/16 mylist = ["xiaohong", "xiaogang&quo ...

  10. Kali-linux使用Metasploit基础

    Metasploit是一款开源的安全漏洞检测工具.它可以帮助用户识别安全问题,验证漏洞的缓解措施,并对某些软件进行安全性评估,提供真正的安全风险情报.当用户第一次接触Metasploit渗透测试框架软 ...