Python 多线程Threading初学教程


Posted in Python onAugust 22, 2017

1.1 什么是多线程 Threading

多线程可简单理解为同时执行多个任务。

多进程和多线程都可以执行多个任务,线程是进程的一部分。线程的特点是线程之间可以共享内存和变量,资源消耗少(不过在Unix环境中,多进程和多线程资源调度消耗差距不明显,Unix调度较快),缺点是线程之间的同步和加锁比较麻烦。

1.2 添加线程 Thread

导入模块

import threading

获取已激活的线程数

threading.active_count()

查看所有线程信息

threading.enumerate()

查看现在正在运行的线程

threading.current_thread()

添加线程,threading.Thread()接收参数target代表这个线程要完成的任务,需自行定义

def thread_job():
  print('This is a thread of %s' % threading.current_thread())
def main():
  thread = threading.Thread(target=thread_job,)  # 定义线程 
  thread.start() # 让线程开始工作
  if __name__ == '__main__':
  main()

1.3 join 功能

因为线程是同时进行的,使用join功能可让线程完成后再进行下一步操作,即阻塞调用线程,直到队列中的所有任务被处理掉。

import threading
import time
def thread_job():
  print('T1 start\n')
  for i in range(10):
    time.sleep(0.1)
  print('T1 finish\n')
def T2_job():
  print('T2 start\n')
  print('T2 finish\n')
def main():
  added_thread=threading.Thread(target=thread_job,name='T1')
  thread2=threading.Thread(target=T2_job,name='T2')
  added_thread.start()
  #added_thread.join()
  thread2.start()
  #thread2.join()
  print('all done\n')
if __name__=='__main__':
   main()

例子如上所示,当不使用join功能的时候,结果如下图所示:

Python 多线程Threading初学教程

当执行了join功能之后,T1运行完之后才运行T2,之后再运行print(‘all done')

Python 多线程Threading初学教程

1.4 储存进程结果 queue

 queue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递

 (1)基本FIFO队列

class queue.Queue(maxsize=0)

maxsize是整数,表明队列中能存放的数据个数的上限,达到上限时,插入会导致阻塞,直至队列中的数据被消费掉,如果maxsize小于或者等于0,队列大小没有限制

(2)LIFO队列 last in first out后进先出

class queue.LifoQueue(maxsize=0)

(3)优先级队列

class queue.PriorityQueue(maxsize=0)

视频中的代码,看的还不是特别明白

import threading
import time
from queue import Queue
def job(l,q):
  for i in range(len(l)):
    l[i]=l[i]**2
  q.put(l)
def multithreading():
  q=Queue()
  threads=[]
  data=[[1,2,3],[3,4,5],[4,5,6],[5,6,7]]
  for i in range(4):
    t=threading.Thread(target=job,args=(data[i],q))
    t.start()
    threads.append(t)
  for thread in threads:
    thread.join()
  results=[]
  for _ in range(4):
    results.append(q.get())
  print(results)
if __name__=='__main__':
   multithreading()

运行结果如下所示

Python 多线程Threading初学教程Python 多线程Threading初学教程

图片截取来源:http://www.cnblogs.com/itogo/p/5635629.html

1.5 GIL 不一定有效率

Global Interpreter Lock全局解释器锁,python的执行由python虚拟机(也成解释器主循环)控制,GIL的控制对python虚拟机的访问,保证在任意时刻,只有一个线程在解释器中运行。在多线程环境中能,python虚拟机按照以下方式执行:

1.设置 GIL

2.切换到一个线程去运行

3.运行:

a.指定数量的字节码指令,或

b.线程主动让出控制(可以调用time.sleep(0))

4.把线程设置为睡眠状态

5.解锁GIL

6.重复1-5

在调用外部代码(如C/C++扩展函数)的时候,GIL将会被锁定,直到这个函数结束为止(由于在这期间没有python的字节码被运行,所以不会做线程切换)。

下面为视频中所举例的代码,将一个数扩大4倍,分为正常方式、以及分配给4个线程去做,发现耗时其实并没有相差太多量级。

import threading
from queue import Queue
import copy
import time
def job(l, q):
  res = sum(l)
  q.put(res)
def multithreading(l):
  q = Queue()
  threads = []
  for i in range(4):
    t = threading.Thread(target=job, args=(copy.copy(l), q), name='T%i' % i)
    t.start()
    threads.append(t)
  [t.join() for t in threads]
  total = 0
  for _ in range(4):
    total += q.get()
  print(total)
def normal(l):
  total = sum(l)
  print(total)
if __name__ == '__main__':
  l = list(range(1000000))
  s_t = time.time()
  normal(l*4)
  print('normal: ',time.time()-s_t)
  s_t = time.time()
  multithreading(l)
  print('multithreading: ', time.time()-s_t)

运行结果为:

Python 多线程Threading初学教程

Python 多线程Threading初学教程

1.6 线程锁 Lock

如果线程1得到了结果,想要让线程2继续使用1的结果进行处理,则需要对1lock,等到1执行完,再开始执行线程2。一般来说对share memory即对共享内存进行加工处理时会用到lock。

import threading
def job1():
  global A, lock #全局变量
  lock.acquire() #开始lock
  for i in range(10):
    A += 1
    print('job1', A)
  lock.release() #释放
def job2(): 
  global A, lock
  lock.acquire()
  for i in range(10):
    A += 10
    print('job2', A)
  lock.release()
if __name__ == '__main__':
  lock = threading.Lock()
  A = 0
  t1 = threading.Thread(target=job1)
  t2 = threading.Thread(target=job2)
  t1.start()
  t2.start()
  t1.join()
  t2.join()

运行结果如下所示:

Python 多线程Threading初学教程

总结

以上所述是小编给大家介绍的Python 多线程Threading初学教程,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
讲解Python中for循环下的索引变量的作用域
Apr 15 Python
利用Python的装饰器解决Bottle框架中用户验证问题
Apr 24 Python
详细讲解Python中的文件I/O操作
May 24 Python
Python无损音乐搜索引擎实现代码
Feb 02 Python
对pytorch网络层结构的数组化详解
Dec 08 Python
Python中一般处理中文的几种方法
Mar 06 Python
Pandas之groupby( )用法笔记小结
Jul 23 Python
Python 中@property的用法详解
Jan 15 Python
Python基础之字符串操作常用函数集合
Feb 09 Python
Python递归实现打印多重列表代码
Feb 27 Python
Python之变量类型和if判断方式
May 05 Python
keras-siamese用自己的数据集实现详解
Jun 10 Python
Python3实现抓取javascript动态生成的html网页功能示例
Aug 22 #Python
Python实现公历(阳历)转农历(阴历)的方法示例
Aug 22 #Python
Python实现的矩阵类实例
Aug 22 #Python
Python实现图片转字符画的示例
Aug 22 #Python
利用aardio给python编写图形界面
Aug 21 #Python
Python实现图片转字符画的示例代码
Aug 21 #Python
Python微信企业号开发之回调模式接收微信端客户端发送消息及被动返回消息示例
Aug 21 #Python
You might like
全国FM电台频率大全 - 3 河北省
2020/03/11 无线电
实现分十页分向前十页向后十页的处理
2006/10/09 PHP
PHP __autoload()方法真的影响性能吗?
2012/03/30 PHP
php去除字符串中空字符的常用方法小结
2015/03/17 PHP
关于laravel框架中的常用目录路径函数
2019/10/23 PHP
Mootools 1.2教程 Fx.Tween的使用
2009/09/15 Javascript
JS动态添加option和删除option(附实例代码)
2013/04/01 Javascript
JQuery拖动表头边框线调整表格列宽效果代码
2014/09/10 Javascript
使用angular写一个hello world
2015/01/23 Javascript
jQuery多个input求和的实现方法
2015/02/12 Javascript
快速学习jQuery插件 Cookie插件使用方法
2015/12/01 Javascript
js和jq使用submit方法无法提交表单的快速解决方法
2016/05/17 Javascript
JS实现将数字金额转换为大写人民币汉字的方法
2016/08/02 Javascript
JS简单验证上传文件类型的方法
2017/04/17 Javascript
Vue多组件仓库开发与发布详解
2019/02/28 Javascript
JS中数据结构与算法---排序算法(Sort Algorithm)实例详解
2019/06/17 Javascript
jQuery子选择器与可见性选择器实例分析
2019/06/28 jQuery
react组件基本用法示例小结
2020/04/27 Javascript
vue实现自定义多选按钮
2020/07/16 Javascript
js异步接口并发数量控制的方法示例
2020/11/22 Javascript
[46:38]完美世界DOTA2联赛PWL S2 Magma vs PXG 第三场 11.28
2020/12/02 DOTA
python读取csv文件示例(python操作csv)
2014/03/11 Python
Python常见格式化字符串方法小结【百分号与format方法】
2016/09/18 Python
教大家玩转Python字符串处理的七种技巧
2017/03/31 Python
Python断言assert的用法代码解析
2018/02/03 Python
Python实现的服务器示例小结【单进程、多进程、多线程、非阻塞式】
2019/05/23 Python
PyCharm 2019.3发布增加了新功能一览
2019/12/08 Python
对tensorflow 中tile函数的使用详解
2020/02/07 Python
Django静态文件加载失败解决方案
2020/08/26 Python
在Pycharm中安装Pandas库方法(简单易懂)
2021/02/20 Python
ETO男装官方网店:ETO Jeans
2019/02/28 全球购物
法学专业毕业生自荐信范文
2013/12/18 职场文书
行政复议决定书
2015/06/24 职场文书
《天净沙·秋思》教学反思三篇
2019/11/02 职场文书
CSS的class与id常用的命名规则
2021/05/18 HTML / CSS
Python基础之变量的相关知识总结
2021/06/23 Python