一篇文章学习Python中的多线程

基本知识:

    • 一、什么是多线程Threading
    • 二、添加线程Thread
    • 三、join功能
    • 四、存储进程结果Queue
    • 五、GIL不一定有效率
    • 六、线程锁 Lock

一、什么是多线程Threading

二、添加线程Thread

import threading                   # 导入模块print(threading.active_count())    # 获取激活的线程数
print(threading.enumerate())       # 查看所有线程信息
print(threading.current_thread())  # 查看正在运行的线程def thread_job():print("This is thread of %s",threading.current_thread())if __name__ == '__main__':print("This is thread of %s",threading.current_thread())thread = threading.Thread(target=thread_job,)   # 定义线程:注意target只写函数名,不能带括号thread.start()                                  # 让线程开始工作

结果:

1
[<_MainThread(MainThread, started 4661450176)>]
<_MainThread(MainThread, started 4661450176)>
This is thread of %s <_MainThread(MainThread, started 4661450176)>
This is thread of %s <Thread(Thread-1, started 123145514528768)>

三、join功能

1. 不使用join()的结果:主线程Main thread 和子线程 Thread1 同时进行

import threading 
import time                  def thread_job():print("Thread1 start")time.sleep(1)                # 模拟任务消耗时间print("Thread1 finish")if __name__ == '__main__':thread = threading.Thread(target=thread_job,name="Thread1")          thread.start() print("All finish")

预期结果:

Thread1 start
Thread1 finish
All finish

实际结果:

Thread1 start
All finish
Thread1 finish

2. 使用join()的结果:在子线程 Thread1 完成之后再执行主线程Main thread

if __name__ == '__main__':thread = threading.Thread(target=thread_job,name="Thread1")          thread.start() thread.join()print("All finish")

结果:

Thread1 start
Thread1 finish
All finish

3. 如果是多个线程,为了规避不必要的麻烦,推荐1221的V型排布

thread_1.start() 
thread_2.start() 
thread_2.join()
thread_1.join()
print("All finish")

四、存储进程结果Queue

import threading 
import time  
from queue import Queue                def thread_job(l,q):          # l:列表,q:队列,功能:计算列表每个元素的平凡,结果保存在队列中for i in range(len(l)):l[i] = l[i]**2q.put(l)                  # 多线程调用的函数不能用return返回值,故用队列保存结果if __name__ == '__main__':q = Queue()data = [[1,2,3],[4,5,6],[7,8,9]]threads = []for i in range(3):        # 定义三个线程t = threading.Thread(target=thread_job,args=(data[i],q))t.start()             # 开启线程threads.append(t)     # 把每个线程加入到线程列表中for thread in threads:    # 将3个线程join到主线程中thread.join()for _ in range(3):print(q.get())        # 使用q.get()按顺序从q中取出结果

结果:

[1, 4, 9]
[16, 25, 36]
[49, 64, 81]

五、GIL不一定有效率

python 多线程有时候并不理想,主要原因是python的设计上有一个必要环节Global Interpreter Lock(GIL)全局锁。使得python还是一次性只能处理一个东西。

尽管Python完全支持多线程编程, 但是解释器的C语言实现部分在完全并行执行时并不是线程安全的。
实际上,解释器被一个全局解释器锁保护着,它确保任何时候都只有一个Python线程执行。
GIL最大的问题就是Python的多线程程序并不能利用多核CPU的优势 (比如一个使用了多个线程的计算密集型程序只会在一个单CPU上面运行)。
在讨论普通的GIL之前,有一点要强调的是GIL只会影响到那些严重依赖CPU的程序(比如计算型的)
如果你的程序大部分只会涉及到I/O,比如网络交互,那么使用多线程就很合适,因为它们大部分时间都在等待。
实际上,你完全可以放心的创建几千个Python线程, 现代操作系统运行这么多线程没有任何压力,没啥可担心的。

import threading
import timedef job():                  # 任务函数for _ in range(10):time.sleep(0.0001)def multiThreading():      # 使用 N 个线程执行任务threads = []for i in range(10):t = threading.Thread(target=job,)t.start()threads.append(t)[t.join() for t in threads]def normal():               # 依次执行任务 N 次for i in range(10):job()if __name__ == '__main__':  # 多线程执行和普通顺序调用消耗时间对比nor_start_time = time.time()normal()print("normal_time:",time.time()-nor_start_time)mul_start_time = time.time()multiThreading()print("multiThreading_time:",time.time()-mul_start_time)

当任务执行10次时普通顺序调用和多线程消耗时间:

normal_time: 0.014399051666259766
multiThreading_time: 0.00513005256652832

按理来说,多线程应该比普通方法速度快10倍,因为建立了10个线程,但是结果并没有。这就是其中的GIL在作怪。

六、线程锁 Lock

1. 不使用 Lock 的情况
在一个线程执行运算修改共享内存的过程中,其他线程也可以访问该共享内存,会造成共享内存数据的混乱。

import threadingdef job1():global Afor i in range(10):A += 1print("Job1:",A)def job2():global Afor i in range(10):A += 10print("Job2:",A)if __name__=="__main__":A = 0t1 = threading.Thread(target=job1)t2 = threading.Thread(target=job2)t1.start()t2.start()t2.join()t1.join()

结果:

Job1: 1
Job1: 2
Job1: 13
Job2: 12
Job1: 14
Job2: 24
Job1: 25
Job2: 35
Job1: 36
Job2: 46
Job1: 47
Job2: 57
Job1: 58
Job2: 68
Job1: 69
Job2: 79
Job1: 80
Job2: 90
Job2: 100
Job2: 110

2. 使用 Lock 的情况
Lock 在不同线程使用同一共享内存时,能够确保线程之间互不影响
方法:在每个线程执行运算修改共享内存之前,执行 lock.acquare() 将共享内存上锁,确保当前线程访问时,共享内存不会被其他线程访问,执行运算完毕后,使用 lock.release() 将锁打开,保证其他线程可以使用该共享内存。

import threadingdef job1():global A,locklock.acquire()       # 上锁for i in range(10):A += 1print("Job1:",A)lock.release()       # 开锁def job2():global A,locklock.acquire()       # 上锁for i in range(10):A += 10print("Job2:",A)lock.release()       # 开锁if __name__=="__main__":A = 0lock = threading.Lock()t1 = threading.Thread(target=job1)t2 = threading.Thread(target=job2)t1.start()t2.start()t2.join()t1.join()

结果:

Job1: 1
Job1: 2
Job1: 3
Job1: 4
Job1: 5
Job1: 6
Job1: 7
Job1: 8
Job1: 9
Job1: 10
Job2: 20
Job2: 30
Job2: 40
Job2: 50
Job2: 60
Job2: 70
Job2: 80
Job2: 90
Job2: 100
Job2: 110

学习视频连接:?莫烦PYTHON

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

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

相关文章

银行技术类2020校园招聘笔试

2019年10月13日 一 选择题 包含银行的成立时间&#xff0c;最大股东&#xff0c;行徽&#xff0c;最大堆&#xff0c;平衡二叉树&#xff0c;二叉排序树&#xff0c;sql基本操作&#xff0c; 函数的调用次数&#xff0c;一串代码的具体输出&#xff0c;网桥&#xff0c;网络协议…

如何配置一台深度学习工作站?

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术这篇文章主要介绍的是家用的深度学习工作站&#xff0c;典型的配置有两种&#xff0c;分别是一个 GPU 的机器和四个 GPU的机器。如果需要更多的 GPU 可以考虑配置两台四个 GPU 的机器。如果希望一台机器同时具…

LeetCode 2. 两数相加(单链表反转)

题目链接&#xff1a;https://leetcode-cn.com/problems/add-two-numbers/ 给出两个 非空 的链表用来表示两个非负的整数。其中&#xff0c;它们各自的位数是按照 逆序 的方式存储的&#xff0c;并且它们的每个节点只能存储 一位 数字。 如果&#xff0c;我们将这两个数相加起…

报名 | 全国知识图谱与语义计算大会(CCKS 2019)评测任务发布

全国知识图谱与语义计算大会是由中国中文信息学会语言与知识计算专委会定期举办的全国年度学术会议。CCKS 2018吸引了来自学术界和工业界的超800人参加。2019 年全国知识图谱和语义计算大会(www.ccks2019.cn) 将于2019年8月24日至8月27日在杭州召开&#xff0c;CCKS 2019的主题…

一篇文章学习Python中的多进程

基本知识&#xff1a;一、什么是多进程 Multiprocessing二、添加多进程 Process三、存储进程输出 Queue四、效率对比 threading & multiprocessing五、进程池 Pool六、共享内存 shared memory七、进程锁 Lock一、什么是多进程 Multiprocessing 支持并行运算&#xff0c;充…

UML是什么?UML常用图以及建模工具有哪些?

“ 在做项目设计方案的时候&#xff0c;理解为需求后&#xff0c;我们都会做技术设计方案&#xff0c;这个时候就需要用到UML建模&#xff0c;涉及到UML常用图形以及工具画图&#xff0c;以下我会详细介绍UML图形和我个人推荐的UML建模工具。 UML即Unified Model Language&am…

炼丹必备!推荐一个超级好用的机器学习云平台

矩池云是一个专业的国内深度学习云平台&#xff0c;拥有着良好的深度学习云端训练体验&#xff0c;和高性价比的自建GPU集群资源。高性价比矩池云拥有很高的性价比&#xff0c;其的计费方式主要分为按时租与按周/月租。按时租用采用的是分钟级的实时计费模式&#xff0c;满足了…

直通BAT必考题系列:深入详解JVM内存模型与JVM参数详细配置

JVM基本是BAT面试必考的内容&#xff0c;今天我们先从JVM内存模型开启详解整个JVM系列&#xff0c;希望看完整个系列后&#xff0c;可以轻松通过BAT关于JVM的考核。 BAT必考JVM系列专题 1.JVM内存模型 2.JVM垃圾回收算法 3.JVM垃圾回收器 4.JVM参数详解 5.JVM性能调优 JV…

论文浅尝 | 基于平行新闻的Bootstrapping关系抽取

笔记整理&#xff1a;吴锐&#xff0c;东南大学大四本科生&#xff0c;研究方向为自然语言处理。Citation&#xff1a;Michael Glass, K. B. . (2012). Bootstrapping relation extraction using parallel news articles. Retrieved from https://pdfs.semanticscholar.org/bfa…

动态规划应用--最长递增子序列 LeetCode 300

文章目录1. 问题描述2. 解题思路2.1 动态规划2.2 二分查找1. 问题描述 有一个数字序列包含n个不同的数字&#xff0c;如何求出这个序列中的最长递增子序列长度&#xff1f;比如2&#xff0c;9&#xff0c;3&#xff0c;6&#xff0c;5&#xff0c;1&#xff0c;7这样一组数字序…

常见的面试题整理 -python

常见的面试题整理 在这里插入代码片 #二分查找def binarySearch(alist, item):first0;lastlen(alist)-1;while first < last:mid(firstlast)/2;print(mid)if alist[mid]>item:lastmid-1;elif alist[mid]<item:firstmid1return -1test[0,1,2,8,13,17,19,9,0]print(bin…

Python中的全局变量

一、全局变量的定义与调用 在主进程中定义的变量属于全局变量&#xff0c;如下面的变量a、b、c&#xff0c;都是全局变量。 如果只是调用全局变量&#xff0c;不对其进行修改&#xff0c;可直接调用。 a 1 b [2,2]def f1():print(a)print(b)print(c) if __name__ __mai…

论文浅尝 | 5 篇顶会论文带你了解知识图谱最新研究进展

本文转载自公众号&#xff1a;PaperWeekly。精选 5 篇来自 ICLR 2019、WSDM 2019、EMNLP 2018、CIKM 2018和IJCAI 2018 的知识图谱相关工作&#xff0c;带你快速了解知识图谱领域最新研究进展。WSDM 2019■ 论文解读 | 张文&#xff0c;浙江大学在读博士&#xff0c;研究方向为…

LeetCode 53. 最大子序和(动态规划)

文章目录1. 题目描述2. 解题2.1 暴力求解2.2 动态规划1. 题目描述 题目链接&#xff1a;https://leetcode-cn.com/problems/maximum-subarray/ 《剑指Offer》同题&#xff1a;面试题42. 连续子数组的最大和 给定一个整数数组 nums &#xff0c;找到一个具有最大和的连续子数组…

java程序员的发展之路和职业规划

在互联网做技术的朋友&#xff0c;往往没有足够的重视&#xff0c;职业规划其实一点都不虚&#xff0c;而是一件非常实在的事情&#xff0c;如果你不是每次碰墙再反思职业规划&#xff0c;而是提前3年左右作出下一步的规划&#xff0c;你早已经走出了一条属于自己的路。 以下是…

Python多进程中多参数问题

要注意的一点是&#xff1a;传递给进程的参数必须是可序列化的&#xff0c;常见的数据类型都是可序列化的&#xff0c;自定义的类一般是不可序列化的&#xff0c;&#xff08;在java中有将自定类写为可序列化的方式&#xff0c;不知道python中有没有&#xff0c;懒得查了&#…

机器学习(Machine Learning)、深度学习(Deep Learning)、NLP面试中常考到的知识点和代码实现

网址&#xff1a;https://github.com/NLP-LOVE/ML-NLP 此项目是机器学习(Machine Learning)、深度学习(Deep Learning)、NLP面试中常考到的知识点和代码实现&#xff0c;也是作为一个算法工程师必会的理论基础知识。 http://mantchs.com/ 此项目是机器学习、NLP面试中常考到的…

图Graph--拓扑排序(Topological Sorting)

文章目录1. 拓扑排序2. 算法实现2.1 Kahn算法2.2 DFS算法2.3 时间复杂度3. 应用4. 类似题目练习一个项目往往会包含很多代码源文件。编译器在编译整个项目时&#xff0c;需按照依赖关系&#xff0c;依次编译每个源文件。比如&#xff0c;A.cpp依赖B.cpp&#xff0c;那在编译时&…

SIGIR20最佳论文:通往公平、公正的Learning to Rank!

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术文 | 机智的叉烧编 | 兔子酱大家好&#xff0c;我是叉烧。感谢卖萌屋再次给我机会在这里分享~SIGIR2020 的 best paper 终于出炉&#xff0c;这次获奖论文是 Controlling Fairness and Bias in Dynamic Learn…

论文浅尝 | 基于属性嵌入的知识图谱间实体对齐方法

笔记整理&#xff1a;张清恒&#xff0c;南京大学计算机科学与技术系&#xff0c;硕士研究生。论文链接&#xff1a;https://people.eng.unimelb.edu.au/jianzhongq/papers/AAAI2019_EntityAlignment.pdf发表会议&#xff1a;AAAI 2019摘要近来&#xff0c;针对跨知识图谱&…