线程和Python

本节主要记录如何在 Python 中使用线程,其中包括全局解释器锁对线程的限制和对应的学习脚本。

全局解释器锁

Python 代码的执行是由 Python 虚拟机(又叫解释器主循环)进行控制的。

  • 对 Python 虚拟机的访问是由全局解释器锁(GIL)控制的。步骤为:

    1. 设置 GIL;

      1. 切换进一个线程去运行;

      2. 执行下面操作之一:

        1. a. 指定数量的字节代码指令;

        2. b. 线程主动让出控制权(可以调用 time.sleep(0) 来完成)。

      3. 把线程设置回睡眠状态(切换出线程);

      4. 解锁 GIL;

      5. 重复上述步骤

退出线程

当一个线程完成函数的执行时,它就会退出。

  • 退出的方法还有:

    • 通过调用如 thread.exit() 之类的退出函数;

    • 如 sys.exit() 之类的退出 Python 进程的标准方法;

    • 抛出 SystemExit 异常,来使线程退出。

  • 不能直接“终止”一个线程;

在 Python 中使用线程

Python 虽然支持多线程编程,但是还需要取决于它所运行的操作系统。

  • 支持多线程的操作系统:绝大多数类 UNIX 平台(如 Linux、Solaris、Mac OS X、*BSD等)以及 Windows 平台;

  • 要确定解释器(或者说你的系统)是否支持线程,可以从交互式解释器中尝试导入 thread 模块,如果可用则不会产生错误。如下:

    • >>> import thread

  • 如果 Python 解释器没有将线程支持编译进去,模块导入将会失败

    • >>> import thread

      Traceback (most recent call last): File "<stdin>", line 1, in <module>ModuleNotFoundError: No module named 'thread'

**注:在 Python 3 中 thread 模块被重命名为 _thread (原因为平常使用不推荐用 thread 模块,只建议那些想访问线程的更底层级别的专家使用)。

不使用线程的情况

通过一个简单的例子代码来演示在不使用线程的情况下是如何工作的,方便后面对比使用线程的情况。以下为代码:

 #!/usr/bin/env python

from time import sleep, ctime

def loop0():
print('start loop 0 at:', ctime())
sleep(4)
print('loop 0 done at:', ctime())

def loop1():
print('start loop 1 at:', ctime())
sleep(3)
print('loop 1 done at:', ctime())

def main():
print('starting at:', ctime())
loop0()
loop1()
print('all DONE at:', ctime())

if __name__ == '__main__':
main()

运行后的输出结果:

 starting at: Sun Jul 22 17:15:13 2018
start loop 0 at: Sun Jul 22 17:15:13 2018
loop 0 done at: Sun Jul 22 17:15:17 2018
start loop 1 at: Sun Jul 22 17:15:17 2018
loop 1 done at: Sun Jul 22 17:15:20 2018
all DONE at: Sun Jul 22 17:15:20 2018

Python 的线程模块

Python 提供了多个模块来支持多线程编程,包括 thread 、threading 和 Queue 模块等。

  • thread 模块提供了基本的线程和锁定支持;

  • threading 模块提供了更高级别、功能更全面的线程管理;

  • Queue 模块可以创建一个队列数据结构,用于在多线程之间进行共享;

  • 在实际进行多线程编程过程中应该避免使用 thread 模块:

    • threading 模块更加先进、有更好的进程支持,thread 模块中的一些熟悉会和 threading 模块冲突;

    • thread 模块拥有的同步原语注释只有一个(同步原语用于控制执行和访问);

      [注释]  常见的比如锁(Lock)、可重入锁(RLock)
    • thread 模块对进程何时退出没有控制。当主线程结束时,所有其它线程也都强制结束,不会发出警告或者进行适当的清理。

线程和Python—Python多线程编程的更多相关文章

  1. Python的多线程编程

    提到多线程,很多人就会望而却步,本文将由浅入深地带你攻克python多线程编程,并防止你跳入深坑, 首先看一段简单的代码: from time import ctime,sleep def play_ ...

  2. python --- 基础多线程编程

    在python中进行多线程编程之前必须了解的问题: 1. 什么是线程? 答:线程是程序中一个单一的顺序控制流程.进程内一个相对独立的.可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程 ...

  3. 【转】使用python进行多线程编程

    1. python对多线程的支持 1)虚拟机层面 Python虚拟机使用GIL(Global Interpreter Lock,全局解释器锁)来互斥线程对共享资源的访问,暂时无法利用多处理器的优势.使 ...

  4. 【Python】多线程编程

    1.thread模块 2.threading模块 3.Queue模块与多线程互斥 简介: thread和threading模块允许创建和管理线程,thread模块提供了基本的线程和锁的支持,而thre ...

  5. Delphi中线程类TThread实现多线程编程1---构造、析构……

    参考:http://www.cnblogs.com/rogee/archive/2010/09/20/1832053.html Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大 ...

  6. 转发 Delphi中线程类TThread 实现多线程编程

    Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchr ...

  7. Python:多线程编程

    1.IO编程 IO(input/output).凡是用到数据交换的地方,都会涉及io编程,例如磁盘,网络的数据传输.在IO编程中,stream(流)是一种重要的概念,分为输入流(input strea ...

  8. python爬虫多线程编程

    #使用了线程库 import threading from queue import Queue from bs4 import BeautifulSoup import json import re ...

  9. Delphi中线程类TThread实现多线程编程2---事件、临界区、Synchronize、WaitFor……

    接着上文介绍TThread. 现在开始说明 Synchronize和WaitFor 但是在介绍这两个函数之前,需要先介绍另外两个线程同步技术:事件和临界区 事件(Event) 事件(Event)与De ...

  10. python 多线程编程

    这篇文章写的很棒http://blog.csdn.net/bravezhe/article/details/8585437 使用threading模块实现多线程编程一[综述] Python这门解释性语 ...

随机推荐

  1. Numpy学习-(2)

    我学习numpy过程的记录 1. 切片和索引 (1) 两种切片方式示例: (2) 多维数组: import numpy as np a = np.array([[1,2,3],[3,4,5],[4,5 ...

  2. 攻防世界Web新手解析

    攻防世界入门的题目 view source 禁用右键,F12审查元素 get post hackbar进行post robots 直接访问robots.txt,发现f1ag_1s_h3re.ph文件, ...

  3. 爬虫与反爬相生相克,道高一丈魔高一尺,如何隐藏ID(附代码)

    Python 反爬篇之 ID 混淆 作为爬虫的一方,如果知道了某个站点的数据自增 ID,那么就能轻而易举把整个站点都爬下来. 是不是有点耸人听闻,你去看很多大站例如油管.P 站等,他们都不会轻易把业务 ...

  4. 2019-2020-1 20199325《Linux内核原理与分析》第八周作业

    Linux内核如何装载和启动一个可执行程序 1.理解编译链接的过程和ELF可执行文件格式,详细内容参考本周第一节:​ 2.编程使用exec*库函数加载一个可执行文件,动态链接分为可执行程序装载时动态链 ...

  5. Python学习15之python内置六大标准类型

    1.六大标准类型:数值型,str,list,set,tuple,dic 2.数值型:int,float,bool,complex 3.区别: 1)数值型和str,tuple都是不可变类型 而list, ...

  6. 获取 ProgramData 文件夹路径

    ]; if (SHGetFolderPathA( NULL, CSIDL_COMMON_STARTUP, NULL, , startUpDir) != S_OK) { printf("SHG ...

  7. 【集群实战】fatab开机挂载失败案例

    1. nfs挂载加入fstab案例 NFS客户端实现fstab开机自启动挂载 现象:nfs开机挂载卸载了/etc/fstab中,结果无法开机自动挂载nfs 解答:1. nfs客户端命令放在/etc/r ...

  8. 【Linux网络基础】网络子网划分基础知识(IP地址,子网)

    一. IP地址分类与子网划分基础 1. 什么是IP地址? 常见的ip地址版本为ipv4, ipv6 32位 4 * 8=32位. 32位二进制数字序列组成的数字序列   点分十进制 采用点将32位数字 ...

  9. 写给Java程序员的Java虚拟机学习指南

    大家好,我是极客时间<深入拆解Java虚拟机>作者.Oracle Labs高级研究员郑雨迪.有幸借这个专题的机会,能和大家分享为何Java工程师要学Java虚拟机?如何掌握Java虚拟机? ...

  10. Vue项目中设置每个单页面的标题

    两种实现方法,第一种方法引入插件,第二种为编程方式实现(推荐) 首先在路由文件index.js中给每个单页面路由添加title routes: [{     path: '/',     name: ...