python多线程与_thread模块
进程与线程
1.进程:计算机程序只是存储在磁盘中的可执行二进制(或其他类型)的文件。只有把他们加载到内存中并被操作系统调用,才具有其生命周期。进程则是一个执行中的程序。每个进程都拥有自己的地址空间,内存,数据栈以及其他用于跟踪执行的辅助数据。进程也可以通过派生新的进程来执行其他任务。由于每个进程有自己的数据,所以只能采用进程间通信(IPC)的方式来共享信息。
2.线程:又称轻量级进程。一个进程开始便会创建一个线程,称为主线程。一个进程可以创建多个线程,多线程即是同一进程下的不同执行路径,同一进程下的线程共享该进程的数据区。线程以并发的方式执行,线程执行时可以被中断和挂起。(在多核cpu中,多线程才可能并行执行)
图解多线程与单线程:单核与多核

线程和python
1.全局解释器锁
python代码执行是由python虚拟机(又称解释器主循环)控制的。python在主循环中同时只能有一个控制线程在执行,就像单核cpu系统中,内存中可以有很多程序,但任意给定时刻只能有一个程序在运行。同理,尽管python解释器可以运行多线程,但在任意给定时刻只有一个线程会被解释器执行。
对python虚拟机由全局解释器锁(GIL)控制。正是由于GIL的存在,python解释器在某一时刻只能让一个线程执行。多线程执行方式如下:
1)设置GIL
2)切换一个线程去执行
3)执行下面操作之一
a.指定数量字节码指令
b.线程让出控制权
4)线程设置成睡眠(挂起)状态
5)解锁GIL
6)重复1-5
2.python多线程的作用,原理,缺陷
作用:提高程序执行速度。
原理:多线程能够提高执行速度的原因是什么?假如一个程序包含多个子任务,这些任务相互独立,没有因果关系。
a.单线程情况下,执行过程中,某个子任务在等待I/O,然而I/O到来的时间不确定,cpu时间耗在毫无意义的等待上,程序执行时间也将加上这一段等待的时间。
b.多线程情况下,若某个子任务等待I/O,可切换出其他线程执行,等到合适的时机(I/O到达)再切换回该线程,避免了cpu无意义的等待,也降低了程序的执行时间。
缺陷:由于GIL的存在,python多线程中只能有一个线程会被执行,因而无法利用多核cpu能够实现并行执行的特点。不仅如此,由于线程的切换需要时间开销,多线程使用不当的程序执行速度还可能要慢于单线程程序执行的速度。
3.python多线程的使用场合
I/O密集型应用
_thread模块
python的_thread模块提供了基本的线程和互斥锁支持,threading模块则提供了功能更全面的线程管理。以下讨论_thread模块
主要方法
_thread.start_new_thread(function,args,kwargs=None) //派生一个新的线程,给定agrs和kwargs来执行function
_thread.allocate_lock() //分配锁对象
_thread.exit() //线程退出
lock.acquire(waitflag=1, timeout=-1) //获取锁对象
lock.locked() //如果获取了锁对象返回true,否则返回false
lock.release() //释放锁
其他方法
_thread.LockType() //锁对象类型
_thread.get_ident() //获取线程标识符
-thread.TIMEOUT_MAX //lock.acquire的最大时间,超时将引发OverflowError
_thread.interrupt_main() //引发主线程KeyboardInterrupt错误,子线程可以用这个函数来终止主线程
简单实例
4个线程分别执行loop函数,中间等待nsec秒,nsec分别为4,2,3,5
1 #!/usr/bin/env python3
2 # coding:utf-8
3 from time import ctime
4 from time import sleep
5 import _thread
6
7 loops = [4, 2, 3, 5]
8
9
10 def loop(nloop, nsec, lock): # 参数依次为:标识,睡眠时间,锁对象
11 print("start loop", nloop, 'at:', ctime())
12 sleep(nsec)
13 print("loop", nloop, "done at:", ctime())
14 lock.release() # 释放锁
15
16
17 def main():
18 print('start at:', ctime())
19 locks = []
20 nloops = range(len(loops))
21
22 for i in nloops:
23 lock = _thread.allocate_lock() # 分配锁对象
24 lock.acquire() # 获取锁对象
25 locks.append(lock)
26
27 for i in nloops:
28 _thread.start_new(loop, (i, loops[i], locks[i])) //派生新线程
29
30 # 等待所有锁被释放
31 for i in nloops:
32 while(locks[i].locked()):
33 pass
34 print('all DONE at', ctime())
35
36
37 if __name__ == '__main__':
38 main()
执行结果:
start at: Mon Jan 22 16:09:10 2018
start loop 2 at: Mon Jan 22 16:09:10 2018
start loop 1 at: Mon Jan 22 16:09:10 2018
start loop 3 at: Mon Jan 22 16:09:10 2018
start loop 0 at: Mon Jan 22 16:09:10 2018
loop 1 done at: Mon Jan 22 16:09:12 2018
loop 2 done at: Mon Jan 22 16:09:13 2018
loop 0 done at: Mon Jan 22 16:09:14 2018
loop 3 done at: Mon Jan 22 16:09:15 2018
all DONE at Mon Jan 22 16:09:15 2018
分别等待4,2,3,5秒,程序运行总时间5秒。main()函数最后一个循环作用是等待所有子线程退出。
注意事项
_thread对于进程何时退出没有任何控制。当主线程结束时,所有其他线程也都强制结束。不会发出警告或者进行适当的清理。因而python多线程一般使用较为高级的threading模块,它提供了完整的线程控制机制以及信号量机制。
可参考:
python多线程与_thread模块的更多相关文章
- python多线程与threading模块
python多线程与_thread模块 中介绍了线程的基本概念以及_thread模块的简单示例.然而,_thread模块过于简单,使得我们无法用它来准确地控制线程,本文介绍threading模块,它提 ...
- python多线程之_thread
多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进 ...
- Python多线程(threading模块)
线程(thread)是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. ...
- python 多线程,tthread模块比较底层,而threading模块是对thread做了一些包装,multithreading
Python多线程详解 2016/05/10 · 基础知识 · 1 评论· 多线程 分享到:20 本文作者: 伯乐在线 - 王海波 .未经作者许可,禁止转载!欢迎加入伯乐在线 专栏作者. 1.多线程的 ...
- python多线程编程-queue模块和生产者-消费者问题
摘录python核心编程 本例中演示生产者-消费者模型:商品或服务的生产者生产商品,然后将其放到类似队列的数据结构中.生产商品中的时间是不确定的,同样消费者消费商品的时间也是不确定的. 使用queue ...
- python 多线程编程之_thread模块
参考书籍:python核心编程 _thread模块除了可以派生线程外,还提供了基本的同步数据结构,又称为锁对象(lock object,也叫原语锁.简单锁.互斥锁.互斥和二进制信号量). 下面是常用的 ...
- 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼
1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...
- python的_thread模块来实现多线程(<python核心编程例子>)
python中_thread模块是一个低级别的多线程模块,它的问题在于主线程运行完毕后,会立马把子线程给结束掉,不加处理地使用_thread模块是不合适的.这里把书中讲述的有关_thread使用的例子 ...
- python _thread模块使用
python关于线程管理的有2个类,_thread(在2.x的版本中叫thread)和threading. # encoding: UTF-8 import thread import time ...
随机推荐
- 【LeetCode】80. 删除有序数组中的重复项 II
80. 删除有序数组中的重复项 II 知识点:数组:排序:双指针: 题目描述 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度. 不要使 ...
- 【现学现卖】th:href标签动态路径设置,thymeleaf获取session中的属性值
update:2020-02-28:按道理来说这个功能在前后端分离的时候应该不怎么用的上,基本到现在我还是没遇到过有这样的需求,不过也是一种方法就是.th:href="@{/{role}/l ...
- 使用F#编写PowerShell模块
▲F#和PowerShell模块 作为可能是人类世界最强大的Shell,PowerShell最大的特点是能够直接在命令间传递.NET对象,而支持这种能力的命令被称作cmdlet.自己编写PowerSh ...
- DataTemplateSelector介绍
DataTemplateSelector可以帮助我们实现动态选择数据绑定的模版,如通过ListView+DataTemplateSelector实现微信朋友圈或聊天列表效果. Github已有聊天效果 ...
- HttpClient 4.3教程-前言
前言 Http协议应该是互联网中最重要的协议.持续增长的web服务.可联网的家用电器等都在继承并拓展着Http协议,向着浏览器之外的方向发展. 虽然jdk中的java.net包中提供了一些基本的方法, ...
- 刷题-力扣-168. Excel表列名称
168. Excel表列名称 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/excel-sheet-column-title 著作权 ...
- T-SQL - query02_查看数据库信息|查看服务器名称|查看实例名
时间:2017-09-29 编辑:byzqy 本篇记录几个查询数据库信息的 T-SQL 语句: 查看数据库信息 查看服务器名称 查看实例名 文件:SQLQuery2.sql /* 说明: SQLQue ...
- asp.NetCore3.1系统自带Imemcache缓存-滑动/绝对/文件依赖的缓存使用测试
个人测试环境为:Asp.net coe 3.1 WebApi 1:封装自定义的cacheHelper帮助类,部分代码 1 public static void SetCacheByFile<T& ...
- 挂载redhat镜像创建本地yum源
上传镜像文件到/mnt文件夹下,或者上传到其他文件夹下 挂载镜像路径/mnt/cdrom 在mnt文件夹下创建cdrom文件夹 创建命令:mkdir cdrom 挂载镜像命令:mount rhel- ...
- Ansible部署及配置介绍
原文转自:https://www.cnblogs.com/itzgr/p/10233932.html作者:木二 目录 一 Ansible的安装部署 1.1 PIP方式 1.2 YUM方式 二 Ansi ...