浅谈 Python 中的多线程。_小詹学 Python的博客-程序员宅基地

640?wx_fmt=jpeg

本文作者:Rocky0249

公众号:Python空间


00.写在之前


大家好,我是 Rocky0429,今天我来写一下 Python 中的多线程。在正式开始之前,我先用比较通俗的语言给大家介绍几个比较重要的概念。


首先是「并发编程」。「并发」其实在我们的生活中随处可见,比如我们去银行存钱,银行如果只有一个窗口并且办业务的人又比较多,那么肯定就是排成一个长长的队伍,这样的体验对我们来说肯定是非常差的。那么该如何解决这个问题呢?那就是多开几个窗口,把人流分散开,这样就减短了我们队伍的长度,减少整体排队的时间。


上面是我们显示生活中遇到的问题,其实在计算机中我们也会遇到这样的问题,那么我们是怎么解决的呢?其实是这样,每次我们运行一个 Python 程序,这个运行中的程序我们称它为「进程」,如果我们想让它快一点,能够像我们上面例子中多开几个窗口并发解决问题一样,我们就要在进程里引入一个更小的东西,那就是「线程」。


我来举一个具体的例子,比如我们每天都会用的微信,每次运行它的时候会产生一个进程,估计大家都碰到过这种情况,就是你在和别人开视频的时候,另外有一个人给你发消息,我们都知道这个时候可以把视频的窗口缩小然后回复另一个人的消息,能完成这样的操作,其实就是微信里的多个线程帮助我们完成了这件事。


在编写 Python 程序的时候我们也会遇到这种“同时”的需求,同时有大量的请求过来,要我们同时对它们进行处理,那么这个处理的方法,就是「多线程」编程。


01.创建「线程」


Python 的标准库中自带了多线程相关的模块,使在 python 中创建线程成了一件很简单的事。与线程相关的模块一共有两个:thread 和 threading。一般情况下我们只需要 threading 即可。


下面我来写一个简单的使用多线程的例子:


import threading
def func(): print('Hello World')
def main():    for i in range(4): t = threading.Thread(target=func) t.start()
if __name__ == '__main__': main()


上面的代码中,我定义了一个 func 函数,然后在 main 函数中通过 for 循环创建了 4 个线程,然后通过将 target = func 的方式去告诉线程执行 func 函数,一切就绪后调用线程的 start 方法运行线程。结果如下:


Hello WorldHello WorldHello WorldHello World


这个结果看起来和我们直接用 for 循环打印四次 Hello World 没什么区别,其实区别还是有的,就是肉眼看不出来而已,下面我来改造一下上面的程序:


import threadingimport time
def func(): print('Hello World') time.sleep(1)
def main(): for i in range(4): t = threading.Thread(target=func) t.start()
if __name__ == '__main__': main()


上面我加了 time.sleep(1),如果只是用 for 循环的话,这个程序至少得运行 4 秒,但是由于我们用的是线程并发运行,其实整个程序只需要花费 1 秒多就可以运行完毕,你可以自行尝试一下,可以 sleep 的时间长点自行体验一下。


当然了,如果你自己不乐意动手,作为关爱读者成长协会的会长,我这还有一个好的办法,且待我再改造一下:


import threadingimport timefrom threading import current_thread
def func(): print(current_thread().getName(),'start') print('Hello World') time.sleep(1) print(current_thread().getName(), 'end')
def main(): for i in range(4): t = threading.Thread(target=func) t.start()
if __name__ == '__main__': main()


上面的改造中引用了 current_thread,对当前运行状态进行一个显示,你可以很好的看到线程在运行中的一些过程,运行结果如下所示:


Thread-1 startHello WorldThread-2 startHello WorldThread-3 startHello WorldThread-4 startHello WorldThread-1 endThread-4 endThread-3 endThread-2 end


02.线程传参


在上面创建线程的例子其实是过于简单了,在我们实际的编程中给程序传递参数是必不可少的,下面我在之前例子的基础上,写一个传递参数的例子:


import threading
def func(cnt, name): for i in range(cnt): print('Hello {}'.format(name))
def main(): names = ['Rocky', 'leey', 'cp3', 'chen'] for i in range(4): t = threading.Thread(target=func, args=(10, names[i])) t.start()
if __name__ == '__main__': main()


上面的程序中,我让 func 接受了两个参数,在 main 函数中定义了一个 names 的列表,之后在创建线程的时候将 names 中的元素传递给不同的线程。由上可以看出在 Python 中线程传递参数也是一件很简单的事,传递的参数都是调用 args,通过元组的形式进行。


03.写在之后


其实很多人认为 Python 的多线程是一个相当“鸡肋”的东西,因为标准的 Python 系统中使用了 GIL(全局解释器锁),它的作用是避免 Python 解释器中的线程问题,这样造成了在任意时刻只有一个线程在执行 Python 代码,这样就“糟蹋”了计算机「多核」的特性。


诚然,“糟蹋”了多核,这样对 CPU 密集型的程序来说,Python 多线程确实没有什么提升,反而会更慢,但我们的程序其实也不是无时无刻在“动弹”的,它们也要等待资源的下载,等待文件的读写,等待用户的输入等等等等,这类操作我们统一称为 I/O 操作,对于这类,才是真正显示 Python 多线程能力的时候。


所以,也不是太“鸡肋”嘛。


640?wx_fmt=jpeg

?长按二维码可以关注噢

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_40787712/article/details/88754141

智能推荐

ubuntu部署vsftpd_他-途的博客-程序员宅基地

1.安装vsftpdsudo apt-get install vsftpd2.在/home/下建立myftp文件夹,权限755,在myftp下创建share文件夹,权限777sudo mkdir -p /home/myftp/share//myftp权限chmod -R 755 /home/myftp//share权限chmod -R 777 /home/myftp/s...

linux 命令语句,Linux下的命令语句_江南小财婆的博客-程序员宅基地

2. 启动weblogic : nohup ./startWebLogic.sh查看weblogic启动输出:tail -f nohup.out3. Linux下WebLogic的wlfullclient生成方法适用于10.3.6在libxia执行:java-jar wljarbuilder.jar4. 在linux下利用weblogic.jar执行自动部署:java -cp/root/Oracl...

html地图缩放比例,百度地图实时侦听鼠标滚轮获取地图zoom缩放级别(示例代码)..._容謹的博客-程序员宅基地

百度地图api提供的获取地图缩放级别的方法比较单一,就一个getZoom()方法,这个方法能够获取一次地图缩放级别,后面随着鼠标滚轮的滚动,地图缩放级别被改变,就无法再获取地图缩放级别了,具体api参考:http://developer.baidu.com/map/reference/index.php?title=Class:%E6%9E%81%E9%80%9F%E7%89%88%E6%A0%B...

华为鸿蒙苹果降价,果然,库克又杀回来了,华为鸿蒙一出来,iPhone就降价了_weixin_39608988的博客-程序员宅基地

去年就趁着华为没芯片,压低iPhone价格,力推不支持5G的苹果手机,没想到趁着这个时间点,库克又来了。出于商业行为,苹果的这一招自然是可以理解的,毕竟天猫618购物节又快到了,中国市场的消费力,全世界有目共睹,面对华为、小米、OV、一加、三星等众多手机品牌的攻势,库克自然是要来分一杯羹的。一般来说,苹果手机降价,会出现在发布新品后,比如iPhone 12发布之后,iPhone 11全系的官网价格...

Web网站压力及性能测试工具WebBench使用指南_weixin_34194551的博客-程序员宅基地

Webbench是知名的网站压力方面的测试工具,它是由Lionbridge公司开发。官方主页:http://home.tiscali.cz/~cz210552/webbench.html在运维工作中,网站压力及性能测试是一项很重要的工作。比如在一个网站上线之前,能承受多大访问量、在大访问量情况下性能怎样,这些数据指标好坏将会直接 影响用户体验。但是,...

Android重力感应实现方式简介_zhiying201039的博客-程序员宅基地

<br />Android中的很多游戏的游戏都使用了重力感应的技术,但其api demo却并没有重力感应的实例(不知道是不是我没找到,找到的朋友麻烦告诉我一下,谢谢),因为开发的需要,就研究了一下重力感应这方面,因为网上关于这方面的东西比较少,所以写出来跟大家交流一下,算是抛砖引玉吧。(ps.因为重力感应式需要真机才能测试的,所以,下面提供的demo程序只能在真机上跑。)<br /> <br />因为官方说明比较含糊难懂,我用最简单的方式讲一下Android重力感应系统的坐标系<br /> <br /> <

随便推点

第三篇:Java中Synchronized原理详解以及锁的升级_张孟浩_jay的博客-程序员宅基地

Java为了解决并发的原子性,提供了以下两个解决方案:1、Synchronized关键字2、Lock管程这篇文章我们先说一下Synchronized关键字,Lock管程等着下篇文章再说。1、Synchronized的三种用法package juc;public class TestSyn { static int x = 0; int y = 0; public static void main(String[] args) throws InterruptedExc

servlet的9大内置对象_卑微柠檬怪的博客-程序员宅基地

隐式对象说明request转译后对应HttpServletRequest/ServletRequest对象response转译后对应HttpServletRespons/ServletResponse对象session转译后对应HttpSession对象application转译后对应ServletContext对象out转译后对应JspWriter对象,其内部关联一个PringWriter对象page转译后对应thisconfig转译后...

mybatis-plus踩坑日记_一个正在努力的菜鸡程序员的博客-程序员宅基地_mybatis plus 坑

今天心血来潮,搭建一套项目,记录一下引入mybatis-plus导致的错误。一:在pom文件中引入了mybatis-plus,但是并没有生效。也没有打印出mybatis-plus的logo。出现了这样的一个错误:Application run failedorg.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'deptServiceImpl': Unsa

ALSA声卡驱动中的DAPM详解之四:在驱动程序中初始化并注册widget和route_Andy_0755的博客-程序员宅基地_dapm_routes

转载自http://blog.csdn.net/droidphone 前几篇文章我们从dapm的数据结构入手,了解了代表音频控件的widget,代表连接路径的route以及用于连接两个widget的path。之前都是一些概念的讲解以及对数据结构中各个字段的说明,从本章开始,我们要从代码入手,分析dapm的详细工作原理: 如何注册widget 如何连接两个widget ...

vue打包时,assets目录 和static目录下文件的处理区别(nodeModule中插件源码修改后,打包后的文件应放在static目录)..._weixin_30469895的博客-程序员宅基地

为了回答这个问题,我们首先需要了解Webpack如何处理静态资产。在*.vue组件中,所有模板和CSS都会被vue-html-loader及css-loader解析,并查找资源URL。例如,在&lt;img src="./logo.png"&gt;和background: url(./logo.png)中,"./logo.png"是相对的资源路径,将由Webpack解...

在linux上装git教程,在各种Linux发行版上安装Git的教程_intplusplus的博客-程序员宅基地

Git是一个流行的开源版本控制系统(VCS),最初是为Linux环境开发的。跟CVS或者SVN这些版本控制系统不同的是,Git的版本控制被认为是“分布式的”,某种意义上,git的本地工作目录可以作为一个功能完善的仓库来使用,它具备完整的历史记录和版本追踪能力。在这种工作模型之下,各个协作者将内容提交到他们的本地仓库中(与之相对的会总是提交到核心仓库),如果有必要,再有选择性地推送到核心仓库。这就为...

推荐文章

热门文章

相关标签