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()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/562567.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JDK1.8的接口新特性

JDK1.8的接口新特性 JDK7及其之前1、接口的变量都是public final static 全局静态常量,无变化。2、接口中都是抽象abstract方法,不能有static方法(因为abstract和static、final、private不能共存)JDK1.8及其之后1、接口中可以添加…

多相机坐标转换_使用KITTI数据集实现坐标转换

本文的主要内容,是讨论如何将KITTI激光雷达的点云数据,映射到图像中去。KITTI数据集是怎么采集的下面这幅图是车的俯视图,可以看到,用到了2个彩色相机,2个灰度相机,1个激光雷达。1个GPS/IMU。图1 KITTI车俯…

内部类-----Java

内部类-----Java 内部类是一类特殊的类,指的是定义在一个类的内部的类,在Java中内部类主要分为非静态内部类、静态内部类、局部 内部类、匿名内部类。 非静态内部类,作为类的成员存在,和成员变量、构造方法、代码块并列。因为是…

静态内部类----Java

静态内部类----Java public class OutClass {//成员变量private static String name;private static int num 10;//构造方法public OutClass(){}public OutClass(String name, int num){this.name name;this.num num;}//成员方法public static void methodOut(){System.out…

api数据加密的定义_API 设计基础规范

首先,请务必记住 API 设计和使用的一个重要法则 Postels Law(又称作稳健性原则):Be liberal in what you accept, be conservative in what you send下面是关于 API 设计的一些基本问题API First将 API 视作产品,并向产品开发一样设计和维护 API在代码实…

匿名内部类----java

匿名内部类----java 匿名内部类就是内部类的简化写法,是一种特殊的局部内部类。 前提:存在一个类或者接口,这里的类可以是具体的类也可以是抽象类。 本质是:一个继承了该类或者实现该接口的子类匿名对象。 适合那种只需要创建…

python视频延迟严重_利用多进程降低opencv视频延迟处理rtsp视频流

Python多进程opencv前几天遇到了一个问题,利用opencv程序调取rtsp视频流,因为处理程序要消耗的CPU时间过于长,VideoCapture的read是按帧读取,所以经常导致内存溢出,延时还高得出奇。所以想到是不是可以利用多进程把读取…

MySQL表级约束和列级约束

MySQL中只要支持六种完整性约束,如表所示:其中check约束是MySQL8中提供的支持。 约束条件 约束描述 primary key 主键约束,约束的值可唯一的标识对应的记录 not null 非空字段的值不能为空 unique 唯一约束,约束1字段的值是…

MySQL外键约束

MySQL外键约束 外键约束(FOREIGN KRY,缩写FK)是用来实现数据库表的参照完整性约束的。 外键约束可以是两张表紧密的结合起来,特别是针对修改或者删除的级联操作时, 会保证数据的完整性。 (注&#xff1…

zookeeper 密码_Dubbo、ZooKeeper介绍

dubbo是一个分布式架构的服务框架,一般结合maven的模块式开发使用。传统的单架构项目,不方便维护和升级;通过maven的模块式开发,就可以把一个单架构的工程,拆封成一个一个的小模块,包括(jar和war)&#xff…

异常--java

java默认的异常处理机制 优点:发生异常后、会给出异常类型、异常提示信息、异常出现的位置 缺点:出现异常后,后续语句不执行了;提示信息太专业,可读性差 解决:try-catch-finally 处理异常;th…

192.168.8.1手机登陆_高端机型都在鼓吹的ufs3.1是什么?对于手机使感受明显吗?...

最近很多朋友留言问,ufs3.1是什么,很重要吗?下面就由小编来给大家介绍一下手机上的ufs3.1是什么!ufs是高端安卓手机,常用的储存协议,就好像我们电脑里的固态硬盘一样,速度越快,打开软…

使用try-catch-finally处理异常---java

package demo02;import java.util.Scanner;public class TestException {public static void main(String[] args) {Scanner input new Scanner(System.in);//输入总分try{System.out.println("请输入总分");int sum input.nextInt();System.out.println("请输…

代码合并工具_11个代码质量审核和管理工具,程序员必备!

「 读者福利!2 TB 各类技术资源免费赠送 」如今,代码质量分析和审核已成为每个企业的基本流程。随着开源代码库使用的增加,安全性和代码质量对于构建高质量软件至关重要。不良的代码不仅会影响代码的可维护性,而且还会在某些情况下…

异常体系----java

一、异常体系 1、error error类层次描述了java运行时系统内部错误和资源耗尽错误,一般指与jvm或动态加载等相关的问题, 如:虚拟机错误,动态链接失败,系统崩溃等。 2、exception 所有异常类的父类,其子…

xy坐标正负方向_【笛卡尔坐标系】

【壹】笛卡尔坐标系(Cartesian coordinates)就是直角坐标系和斜坐标系的统称。相交于原点的两条数轴,构成了平面放射坐标系。如两条数轴上的度量单位相等,则称此放射坐标系为笛卡尔坐标系。两条数轴互相垂直的笛卡尔坐标系,称为笛卡尔直角坐标…

throw和throws的使用

throw和throws的使用 public class Person {private String name;private int age;public Person(){}Person(String name,int age){this.name name;this.age age;}public int getAge() {return age;}public String getName() {return name;}public void setName(String name…

python解决最优化问题_python实现最优化算法

二分法函数详见rres,此代码使该算法运行了两次def asdf(x):rres8*x**3-2*x**2-7*x3return rresi2left0right1while i>0 :i i-1ans 0.1mid1 (left right ans) / 2mid2 (left right - ans) / 2aasdf(mid1)casdf(mid2)if a > c :right mid1else :left m…

为什么需要包装类?

1、某些方法的参数必须是对象,为了让基本数据类型的数据能作为参数,提供包装类。 2、包装类还可以提供更多的功能 3、其他特别重要的功能:比如可以实现字符串和基本数据类型之间的转换 认识一下包装类吧! package demo05;impor…

python自动计算多个教学班的优秀率_第二个月课堂009python之总结(002)

python7天的总结------------------------------------------------------------------------------------------------评价:1、函数 def 自定义行数和内建函数2、re模块3、python3和python的去别4、字典,元组,列表,元组&#xf…