浅谈 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

智能推荐

NSStringDrawingOptions_yinachong的博客-程序员宅基地

NSStringDrawingTruncatesLastVisibleLine:如果文本内容超出指定的矩形限制,文本将被截去并在最后一个字符后加上省略号。如果没有指定NSStringDrawingUsesLineFragmentOrigin选项,则该选项被忽略。NSStringDrawingUsesLineFragmentOrigin:绘制文本时使用 line fragement or

条件注解@ConditionalOnBean失效原因_zhm_sky的博客-程序员宅基地_conditionalonbean不生效

测试环境(配置类)@Import({User.class,Pet.class})@Configuration(proxyBeanMethods = true)public class MyConfig { @Bean @ConditionalOnBean(name = "cat") public User user(){ return new User("航书", 12); } @Bean("cat") public

一重指针、二重指针做函数参数的深刻分析(虽然很基础,但要深刻理解)_ShenHang_的博客-程序员宅基地

一重指针做函数参数#include<iostream>using namespace std;void change(int *p){ *p = 20; p++; cout << p << endl;}int main() { int a = 10; change(&a); cout << &a <&lt...

java设置图片点击渐变透明,图片实现渐变/透明效果_weixin_39569753的博客-程序员宅基地

众所周知,图片等一些盒子都可以利用opacity属性来设置不透明度,但是前两天我朋友忽然给我一个截图,截图效果如下图中红框圈住的位置图片或者说摄像头采集的画面出现了渐变到透明,可以清楚的看到可以看到后面小哥的胳膊,然后问我如何实现这种效果,这下把我难住了(呵 天天给我出难题),我开始在个大论坛开始寻找解决方案;忽然在前天,日常逛论坛时看到一个文字投影的效果,而后忽然灵机一动就想,能不能变相的实现前...

java笔记_笑容温暖城寨的博客-程序员宅基地

安卓课的Java扩展笔记包类命名规范总结输出换行与不换行mian方法中的args参数Math类快捷输出语句static关键字定义无参方法定义带返回值方法包package com.eoe.basic.day01;//包名 在java当中用.表示windos中的/,一般格式:com.公司名.项目名.业务模块名称例如:com.sina.crm.user类命名规范总结1、java中可以有多个类2、java中可以有多个类,但是最多只有一个类的类名和文件名相同3、如果一个类被public修饰,那该类

一、网络游戏架构的前世今生(2)_王元恺David的博客-程序员宅基地

网络游戏架构演进史,优化游戏网络,自定义网络协议

随便推点

fineui mysql_FineUI 相关_卖家胖蝌蚪的博客-程序员宅基地

FineUI 开源版(原ExtAsp.Net)Last updated:2017-03SURFSKYhttp://pan.baidu.com/share/home?uk=170857326#category/type=0---------------------------------------------------配置&预设http://fineui.com/demo/#/demo/...

手把手教你使用FineUI+动软代码生成器开发一个b/s结构的取送货管理信息系统(附源码)之开篇_编程鸭的博客-程序员宅基地

一 本系列随笔概览及产生的背景近阶段接到一些b/s类型的软件项目,但是团队成员之前大部分没有这方面的开发经验,于是自己选择了一套目前网上比较容易上手的开发框架(FineUI),计划录制一套视频讲座,来讲解如何利用FineUI快速开发一个小型的b/s结构的管理系统,已达到帮助团队成员快速掌握b/s结构信息系统的开发方法。源码位置:https://github.com/kamiba/FineU...

[原创]FineUI秘密花园(一) — 为什么选择FineUI?_weixin_33778778的博客-程序员宅基地

首先来看看FineUI是什么? FineUI 是一组基于 ExtJS 的专业 ASP.NET 控件库,拥有原生的 AJAX 支持和华丽的 UI 效果。 FineUI 的使命是创建没有 JavaScript,没有 CSS,没有 UpdatePanel,没有 ViewState,没有 WebServices 的网站应用程序。   从这段官方描述中,我们看到了三个信息点: ...

FineUI布局应用(二)_weixin_30767921的博客-程序员宅基地

一、FineUI页面布局分为 1、Fit布局 1 <f:Panel ID="Panel1" Title="布局Fit(Layout=Fit)" runat="server" Layout="Fit" Height="300px" EnableFrame="true" EnableCollapse="true" 2 BodyPa...

[蓝桥杯][2019年第十届真题]修改数组_深夜面包的博客-程序员宅基地

题目链接:修改数组解题思路:用并查集思路,如果一个数的父节点就是当前数的位置,如果标记下一个数值一样的数的位置+1#include<bits/stdc++.h>#define x first#define y second#define mem1(h) memset(h,-1,sizeof h)#define mem0(h) memset(h,0,sizeof h)#define mcp(a,b) memcpy(a,b,sizeof b)using namespace std

GO语言博客系统——(一、基础部分)_深夜学习家的博客-程序员宅基地_go 博客系统

目录前言一、简单go web程序1.简单程序2.注意点二、路由1.路由比较2.请求路径正则三、中间件总结前言菜鸡自留地,如有错误请指正谢谢。一、简单go web程序1.简单程序package mainimport ( "fmt" "net/http")func handlerFunc(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "<h1&.