Python多线程及其基本使用方法实例分析


Posted in Python onOctober 29, 2019

本文实例讲述了Python多线程及其基本使用方法。分享给大家供大家参考,具体如下:

学习Python的多线程(Multi-threading),至少应该要有进程与线程的基本概念,可以参考:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html。

1.Python中的多线程

执行一个程序,即在操作系统中开启了一个进程,在某一时刻,一个CPU内核只能进行一个进程的任务,现在的计算机所说的多进程/多任务其实是通过加快CPU的执行速度来实现的,因为一个CPU每秒能执行上亿次的计算,能够对进程进行很多次切换,所以在人为可以感知的时间里,看上去,计算机确实是在同时执行多个程序,即同时处理多个进程。
一个进程中可以包含有多个线程,这多个线程为实现该进程的某个主要功能而运行着,多个线程可以进行串行工作,也可以并发同时进行工作,显然后者可以节省更多的时间。

在Python中是支持多线程并发执行的,只是Python中的多线程只能利用单核,也就是说Python中的某一个进程的多个线程只能在一个CPU核心上运行,而不能分配在多个CPU核心中运行,这是考虑到线程安全的缘故,而Python中的GIL则保证了线程安全。关于Python中的GIL,可以参考下面一篇文章:《浅析Python的GIL和线程安全》。

下面是自己在学习过程中的一些课堂笔记,因为还没有真正学习一些理论,所以可能会有些错误,但目前是方便自己的理解:

即GLI是以CPU核心为单位来控制全局锁,所以是不能跨不同的CPU(核心 )的GLI可以保证同一个进程中,某一个线程的共享数据在某一时刻只能同时被另外一个线程修改(使用),而不能同时被多个线程修改(使用),如果去掉GLI,则需要自己为线程加锁,这样之后,性能比原来还要差。

当然,难道就不能充分利用多核CPU或多个CPU了?

做成多进程就可以了,不同的进程运行在不同的CPU(核心)上,也可以实现并发,只是这样的话就会比较浪费内存空间,考虑同时运行10个QQ程序的情况,假如1个QQ占用500M的内存空间,则10个QQ就要占用5G的内存空间了。但如果是多线程的话,可能10个QQ还是共享着这500M的内存空间。还有一个缺点就是,多进程间的数据直接访问可能会比较麻烦,但其实也是可以实现的,比如chrome浏览器就是用多进程实现的。

目前首先要明确的是,Python中是不能把一个进程的多个线程分布在不同的CPU核心上运行的。

2.Python多线程使用方法1

给出下面的程序代码及注释:

import threading  #Python多线程模块
import time
def run(num):
  print 'Hi, I am thread %s..lalala' % num
  time.sleep(1)
for i in range(20):
  t = threading.Thread(target=run, args=(i,))  #多线程使用方法,target为需要执行多线程的函数,args为函数中的参数,注意这里的参数写成(i,),即如果只能一个参数,也要加上一个","
  t.start()  #开始执行多线程

程序运行结果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day6$ python thread4.py
Hi, I am thread 0..lalala
Hi, I am thread 1..lalala
Hi, I am thread 2..lalala
Hi, I am thread 3..lalala
Hi, I am thread 4..lalala
Hi, I am thread 5..lalala
Hi, I am thread 6..lalala
Hi, I am thread 7..lalala
Hi, I am thread 8..lalala
Hi, I am thread 9..lalala
Hi, I am thread 10..lalala
Hi, I am thread 11..lalala
Hi, I am thread 12..lalala
Hi, I am thread 13..lalala
Hi, I am thread 14..lalala
Hi, I am thread 15..lalala
Hi, I am thread 16..lalala
Hi, I am thread 17..lalala
Hi, I am thread 18..lalala
Hi, I am thread 19..lalala

直接看执行结果是看不出什么的,这里说一下这个程序的执行过程:0到19是同时打印输入的,在打印19后,程序sleep 1秒后才结束程序的运行。

上面这个程序有20个线程执行,每个线程都是:打印字符串+sleep(1)。我们实际看到的结果是0到19同时打印,然后才sleep 1秒,但是需要注意的是,并非是20个线程才执行一次sleep(1),而是在每个线程中都执行了一次sleep(1),即该程序实际上是执行了20次sleep(1),而我们实际看到的结果是程序运行时仅仅是暂停了1秒,那是因为这20次sleep(1)是并发执行的。

上面的程序可以这么去理解:20个线程相当于有20匹马,20匹马同时起跑(打印字符串),然后以同时停1秒(sleep(1)),最后同时到达终点(20个线程运行结束,即程序执行结束)。

为了更好的理解上面的程序,可以把上面的代码改为如下:

import threading
import time
def run(num):
  print 'Hi, I am thread %s..lalala' % num
  time.sleep(1)
for i in range(20):
  t = threading.Thread(target=run, args=(i,))
  t.start()
  t.join()  #等上一个线程执行完后再执行下一个线程

执行结果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day6$ python thread4.py
Hi, I am thread 0..lalala
Hi, I am thread 1..lalala
Hi, I am thread 2..lalala
Hi, I am thread 3..lalala
Hi, I am thread 4..lalala
Hi, I am thread 5..lalala
Hi, I am thread 6..lalala
Hi, I am thread 7..lalala
Hi, I am thread 8..lalala
Hi, I am thread 9..lalala
Hi, I am thread 10..lalala
Hi, I am thread 11..lalala
Hi, I am thread 12..lalala
Hi, I am thread 13..lalala
Hi, I am thread 14..lalala
Hi, I am thread 15..lalala
Hi, I am thread 16..lalala
Hi, I am thread 17..lalala
Hi, I am thread 18..lalala
Hi, I am thread 19..lalala

执行结果看上去跟前面是一样的,但执行过程却是这样的:每打印一次字符串,再暂停一秒。

通过这个程序,也就可以更好的理解Python的多线程并发执行了,当然,因为这是一个动态的过程,所以把程序执行一遍后会有更好的理解。

3.Python多线程使用方法2

程序代码如下:

import threading,time
class MyThread(threading.Thread):
  def __init__(self, num):
    threading.Thread.__init__(self)
    self.num = num
  def run(self): #this name must be 'run'
    print 'I am thread %s' % self.num
    time.sleep(2)
for i in range(20):
  t = MyThread(i)
  t.start()

程序的执行结果与方法1是一样的,这里就不给出了,只是这里利用了面向对象编程的思想方法来设计程序代码。

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python 12306抢火车票脚本 Python京东抢手机脚本
Feb 06 Python
Python机器学习库scikit-learn安装与基本使用教程
Jun 25 Python
python实现简单http服务器功能
Sep 17 Python
Python爬取爱奇艺电影信息代码实例
Nov 26 Python
Python之Class&Object用法详解
Dec 25 Python
Pytorch中.new()的作用详解
Feb 18 Python
在python3中实现查找数组中最接近与某值的元素操作
Feb 29 Python
详解Python设计模式之策略模式
Jun 15 Python
Python Excel vlookup函数实现过程解析
Jun 22 Python
python实现文件分片上传的接口自动化
Nov 19 Python
matplotlib源码解析标题实现(窗口标题,标题,子图标题不同之间的差异)
Feb 22 Python
用Python爬取英雄联盟的皮肤详细示例
Dec 06 Python
基于python的itchat库实现微信聊天机器人(推荐)
Oct 29 #Python
pygame实现非图片按钮效果
Oct 29 #Python
线程安全及Python中的GIL原理分析
Oct 29 #Python
pygame实现贪吃蛇游戏(下)
Oct 29 #Python
python TK库简单应用(实时显示子进程输出)
Oct 29 #Python
pygame实现贪吃蛇游戏(上)
Oct 29 #Python
利用Python小工具实现3秒钟将视频转换为音频
Oct 29 #Python
You might like
对text数据类型不支持代码页转换 从: 1252 到: 936
2011/04/23 PHP
PHP利用hash冲突漏洞进行DDoS攻击的方法分析
2015/03/26 PHP
php中Ioc(控制反转)和Di(依赖注入)
2017/05/07 PHP
PHP 结合 Boostrap 结合 js 实现学生列表删除编辑及搜索功能
2019/05/21 PHP
php设计模式之工厂方法模式分析【星际争霸游戏案例】
2020/01/23 PHP
js与jquery获取父级元素,子级元素,兄弟元素的实现方法
2014/01/09 Javascript
使用npm发布Node.JS程序包教程
2015/03/02 Javascript
JavaScript 中有关数组对象的方法(详解)
2016/08/15 Javascript
详解JavaScript的内置对象
2016/12/07 Javascript
webpack开发环境和生产环境的深入理解
2018/11/08 Javascript
Vue 组件注册实例详解
2019/02/23 Javascript
微信小程序实现pdf、word等格式文件上传的方法
2019/09/10 Javascript
TypeScript魔法堂之枚举的超实用手册
2020/10/29 Javascript
[46:47]2014 DOTA2国际邀请赛中国区预选赛 DT VS HGT
2014/05/22 DOTA
python笔记(1) 关于我们应不应该继续学习python
2012/10/24 Python
使用httplib模块来制作Python下HTTP客户端的方法
2015/06/19 Python
举例讲解Python中metaclass元类的创建与使用
2016/06/30 Python
Python3编程实现获取阿里云ECS实例及监控的方法
2017/08/18 Python
获取python文件扩展名和文件名方法
2018/02/02 Python
Django 跨域请求处理的示例代码
2018/05/02 Python
python3实现名片管理系统
2020/11/29 Python
三个python爬虫项目实例代码
2019/12/28 Python
Django 解决新建表删除后无法重新创建等问题
2020/05/21 Python
Python使用tkinter实现摇骰子小游戏功能的代码
2020/07/02 Python
伦敦高达60%折扣的钻石珠宝商:Purely Diamonds
2018/06/24 全球购物
MAC Cosmetics巴西官方网站:M·A·C彩妆
2019/04/18 全球购物
.NET程序员的数据库面试题
2012/10/10 面试题
EJB需直接实现它的业务接口或Home接口吗,请简述理由
2016/11/23 面试题
师范生自荐信
2013/10/27 职场文书
大学运动会通讯稿
2014/01/28 职场文书
作弊检讨书1000字
2014/02/01 职场文书
秋季运动会广播稿
2014/02/22 职场文书
蛋糕店创业计划书
2014/05/06 职场文书
2014县委书记党的群众路线教育实践活动对照检查材料思想汇报
2014/09/22 职场文书
党员剖析材料范文
2014/09/30 职场文书
2015秋季开学典礼新闻稿
2015/07/17 职场文书