python3多线程编程_Python 3多线程编程学习笔记-基础篇
本文是学习《Python核心编程》的学习笔记,介绍了Python中的全局解释器锁和常用的两个线程模块:thread, threading,并对比他们的优缺点和给出简单的列子。
全局解释器锁(GIL)
Python代码的执行都是有Python虚拟机进行控制的。当初设计Python的时候,考虑在主循环中只能有一个控制线程在执行,就像单核CPU进行多线程编程一样。
怎么做到这样控制的呢?就是这里的GIL来控制的,这个锁用来保证同时只有一个线程在运行。
执行方式:
这几个细节知识点:
当调用外部代码(C/C++扩展的内置函数)时, GIL会保持锁定,知道函数执行结束
对于面向I/O的Python例程,GIL会在I/O调用前被释放,从而允许其他线程在I/O执行期间运行
如果是针对计算密集型的操作代码,该线程整个时间片内更倾向于始终占有处理器和GIL。
所以,针对Python虚拟机单线程(GIL)的设计原因,只有线程在执行I/O密集型的应用,才能更好的发挥Python的并发性。
对比thread,threading
Python多个模块可以进行多线程编程,包括:thread,threading等。他们都可以用来创建和管理线程。
thread模块提供了基本的线程和锁定支持,而threading模块提供了更高级别,功能更全面的线程管理。
推荐使用更高级别的threading模块,下面是一个简单的对比:
特征要素
thread
threading
功能全面性
基本(偏底层)
全面,高级
守护进程
不支持
支持
线程同步原语
仅1个(Lock)
很多(Lock,Semaphore,Barrier...)
守护进程讲解
守护进程一般是一个等待客户端请求服务的服务器。如果没有客户端请求,守护进程一般是空闲的。一般把一个线程设置成守护进程,就表示这个线程是不重要的。所以进程退出时是不需要等待这个守护线程完成的。
但是原先的thread 模块是不区分守护或者非守护进程的,也就是说当主线程退出的时候,所有子线程都将终止,而不管他们是否仍在工作。如果你不想这种情况发生,那么就可以采用threading模块。整个Python程序(一般为主线程)将在所有非守护进程退出是才会退出。
设置守护进程,在线程启动之前设置:thread.daemon = True
多线程实践
threading实例
方式1:创建一个thread实例,传递它一个函数
import threading
from time import sleep, ctime
sleep_times = [4, 2]
def loop(threadNo, sleep_time):
print('Start loop', threadNo, 'at:', ctime())
sleep(sleep_time) #Sleep一段时间
print('loop', threadNo, 'done at:', ctime())
def main():
print('starting at:', ctime())
threads = []
threadIds = range(len(sleep_times))
for i in threadIds:
thread = threading.Thread(target=loop, args=(i,sleep_times[i]))
threads.append(thread)
for t in threads:
# 依次启动线程
t.start()
for t in threads:
# 等待所有线程完成
t.join() #将等待线程结束
print('all Done at :', ctime())
if __name__ == '__main__':
main()
方式2:派生Thread的子类,并创建子类的实例
import threading
from time import sleep, ctime
sleep_times = [4, 2]
class MyThread(threading.Thread):
def __init__(self, func, args, name=''):
threading.Thread.__init__(self)
self.func = func
self.name = name
self.args = args
def run(self):
self.func(*self.args)
def loop(threadNo, sleep_time):
print('Start loop', threadNo, 'at:', ctime())
sleep(sleep_time) # Sleep一段时间
print('loop', threadNo, 'done at:', ctime())
def main():
print('starting at:', ctime())
threads = [] # 用于存储所有线程实例的列表
threadIds = range(len(sleep_times))
for i in threadIds:
# 创建线程实例
thread = MyThread(loop, (i, sleep_times[i]))
threads.append(thread)
for t in threads:
# 依次启动线程
t.start()
for t in threads:
# 等待所有线程完成
t.join() # 将等待线程结束
print('all Done at :', ctime())
if __name__ == '__main__':
main()
thread实例
由于本人使用的python3.6,这个thread已经变成_thread
import _thread
from time import sleep, ctime
sleep_times = [4, 2]
def loop(threadNo, sleep_time, lock):
print('Start loop', threadNo, 'at:', ctime())
sleep(sleep_time) #Sleep一段时间
print('loop', threadNo, 'done at:', ctime())
lock.release() #释放锁
def main():
print('starting at:', ctime())
locks = []
threadIds = range(len(sleep_times))
for i in threadIds:
#通过调用_thread.allocate_lock获得锁对象
lock = _thread.allocate_lock()
#通过acquire()方法取得锁
lock.acquire()
locks.append(lock)
for i in threadIds:
# 依次启动线程
_thread.start_new_thread(loop, (i, sleep_times[i], locks[i]))
for i in threadIds:
# 如果当前的锁Lock没有释放的话,一直循环等待
while locks[i].locked():
pass
print('all Done at :', ctime())
if __name__ == '__main__':
main()
python3多线程编程_Python 3多线程编程学习笔记-基础篇相关推荐
- MySQL学习笔记-基础篇1
MySQL 学习笔记–基础篇1 目录 MySQL 学习笔记--基础篇1 1. 数据库概述与MySQL安装 1.1 数据库概述 1.1.1 为什么要使用数据库 1.2 数据库与数据库管理系统 1.2.1 ...
- Redis学习笔记①基础篇_Redis快速入门
若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 资料链接:https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA( ...
- MySQL学习笔记-基础篇2
MySQL学习笔记-基础篇2 目录 MySQL学习笔记-基础篇2 8.子查询 8.1 需求分析与问题解决 8.1.1 实际问题 8.1.2 子查询的基本使用 8.1.3 子查询的分类 8.2 单行子查 ...
- 易语言学习笔记——基础篇
易语言学习笔记20180710 一. 易语言的数据类型可以分为基本数据类型和特殊数据类型 1. 其中基本数据类型分为: ① 数值型 ② 逻辑型 ③ 日期时间型 ④ 文本型 ⑤ ...
- Python学习笔记——基础篇【第五周】——模块
模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...
- java学习笔记-基础篇
Java基础篇 1-12 常识 13 this关键字 14参数传递 16 继承 17 访问权限 28-31异常 1-12 常识 1.文件夹以列表展示,显示扩展名,在地址栏显示全路径 2.javac编译 ...
- extlink.php,ExtJs 学习笔记基础篇 Ext组件的使用_extjs
昨天刚接触到Extjs,简单写了篇学习笔记,今天继续. 天介绍一下Ext中组件举几个简单的例子做说明.注意:文章内容有些摘自本人学习过程中看到的资料. Ext2.0对框架进行了非常大的重构,其中最重要 ...
- C++ 学习笔记----基础篇
(一)类和抽象数据类型 1.通过类实现的接口(公有和私有)可实现信息隐藏.实现对数据的封装等: 2.抽象数据类型(ADT:Abstract Data Type):当一个数据类型仅暴露公有接口,而将 ...
- 扇贝编程python无法退款_扇贝编程python学习笔记-基础篇1
我要成为一个勤奋努力上进的人 第一关 学习用时:15min 随堂测验+上机作业:10min 随堂作业正确率:4/5 1.尝试执行代码 import random menu = ['粉丝', '炒饭', ...
最新文章
- where引导的定语从句与状语从句区别
- json 序列化 java_Java JSON序列化杂谈
- 微软想将新版Edge浏览器引入Linux
- SpringBoot 2.x yml 文件中自定义参数解析对象
- 【心情】最近实在是太忙了,没有心情写东西!
- 实验八 java多线程操作_20182310实验八实验报告
- 单片机ADC采样算法----加权递推平均滤波法
- 4月23日云栖精选夜读:阿里AI新物种!设计机器人两年赶上资深员工水平
- 【网络基础】《TCP/IP详解》学习笔记6
- linux mysql skip_skip-grant-tables 修改linux的mysql忘记root密码
- linux修改dns地址的三种方法
- 如何用计算机术语写论文,计算机毕业论文结论怎么写?
- 根据四个特征点求解相机位姿
- 全球与中国云计算数据中心IT资产处置(ITAD)市场深度研究分析报告
- C++实现二叉树 前、中、后序遍历(递归与非递归)非递归实现过程最简洁版本
- c#.net连接access数据库
- STM32 自定义HID USB设备的实现
- error uploading crisocket: timed out waiting for the conditionswapoff -a # will turn off the swap
- 屏幕适配和百分比布局
- windows 向 iPad导入文件
热门文章
- oracle中 start with,Oracle中connect by...start with...的使用
- 调用第三方接口的几种请求方式
- 使用java向ftp上传多张图片_ftp免费空间,利用ftp工具定时连接ftp免费空间教程及java配置...
- 小程序如何调用php程序,微信小程序调用PHP后台接口 解析纯html文本
- 忽视大小写函数_使用率低但功能强大的6个Excel函数公式应用技巧解读!
- JavaScript 的 Date 方法的使用
- java 三级考试_java三级考试理论题
- Java 源码--Arrays
- ajax调用java程序,从微信小程序到鸿蒙JS开发-JS调用Java
- java线程安全例子_Java总结篇系列:Java多线程(三)