知行编程网知行编程网  2022-03-02 08:00 知行编程网 隐藏边栏 |   抢沙发  6 
文章评分 0 次,平均分 0.0

这是菜鸟学Python的第59篇原创文章

阅读本文大概需要5分钟

   

        上一篇我讲了关于Python中并发编程中的老大哥进程,今天来讲讲它的小弟-线程。前面天有同学给我留言说讲理论很枯燥,是的我非常赞同这个同学的观点,但是理论的东西是基础,是前提,若地基不牢,上面再漂亮的楼阁都是浮云,所谓万丈高楼平地起,基础还是需要打牢的.

 

另外,我个人的感受时候:

第一步:理论知识是必须要熟练掌握

第二步:按照这些招数运用写一些项目,吸收优秀的编程思想和代码

第三步:忘掉那些固定的招数,把它融汇融合,自己创造一些项目,然后随心所欲的驾驭这些知识

当然要达到第三步是需要花很多很多时间和刻苦的练习的,还需要有一些好奇心,所以我这边奉劝一些小伙伴,不要心急~~

 

先看一个总览图,看看线程入门要掌握的知识点

玩转Python多线程|入门篇

 

1.GIL(全局解释器锁)

为啥要介绍GIL,这家伙跟我们将线程有什么关系呢,是这样的Python 代码的执行是由Python 虚拟机(又名解释器主循环)进行控制的

  • Python 在设计时是这样考虑的,在主循环中同时只能有一个控制线程在执行,就像单核CPU 系统中的多进程一样。
  • 内存中可以有许多程序,但是在任意给定时刻只能有一个程序在运行。
  • 同理,尽管Python 解释器中可以运行多个线程,但是在任意给定时刻只有一个线程会被解释器执行。

     

这个GIL就好比一个严厉的管家,他会保证同时只能有一个线程运行的。

在多线程环境中,Python 虚拟机将按照下面所述的方式执行

1).设置GIL。

2).切换进一个线程去运行。

3).执行下面操作之一。

a).指定数量的字节码指令。

b).线程主动让出控制权(可以调用time.sleep(0)来完成)。

4).把线程设置回睡眠状态(切换出线程)。

5).解锁GIL。

6).重复上述步骤。

 

2.什么是线程

1).线程(有时候称为轻量级进程)与进程类似,不过它们是在同一个进程下执行的.

  • 线程会共享相同的上下文。一个进程中的各个线程与主线程共享同一片数据空间,因此相比于独立的进程而言,线程间的信息共享和通信更加容易。
  • 线程一般是以并发方式执行的,正是由于这种并行和数据共享机制,使得多任务间的协作成为可能

     

2).Python线程中的模块:thread和threading模块

Python 提供了多个模块来支持多线程编程,包括 thread、threading 和 Queue 模块等.

  • 程序是可以使用 thread 和 threading 模块来创建与管理线程。thread 模块提供了基本的线程和锁定支持
  • 而 threading 模块提供了更高级别、功能更全面的线程管理
  • 一般我们建议用threading(thread有很多缺点,比如不支持守护线程,当主线程结束时,所有其他线程也都强制结束 ,而且Python3现在主推threading模块)

 

 

3.Python中线程的使用

1).线程的创建,启动,阻塞

我们重点讲解threading模块的线程创建,其实Python中的线程和进程的使用很类似,大家看完下面的几个例子就明白了.

 

玩转Python多线程|入门篇

>>

Starting :      Sun Mar 05 20:04:36 2017

Start loop :      Sun Mar 05 20:04:36 2017

Sleep 3 seconds...

All Done :      Sun Mar 05 20:04:39 2017

 

a).先申明一个loop函数,这个函数很简单,传入一个sleep时间,打印一下启动的时间,然后sleep几秒

 

b).然后申明一个main函数,这里用 threading.Thread来生成一个类的对象,类的入门参数有很多,经常用的是target和args,target就是你要调用的函数名字(其实就是函数的地址),args就是要传递进target函数的参数(主要是一个元组,当只有一个参数的时候,后面要加逗号)

 

c).生成的线程对象t,然后调用t.start()来启动线程,然后t.join()阻塞,一直等到线程完成,打印‘All Done’

 

2).线程的派生类

在使用线程的时候,除了上面创建的方法之外,我们还会经常用线程的派生类来操作(为啥要用派生类,因为当你代码多的时候,用派生类很干净,整洁,容易维护).

 

玩转Python多线程|入门篇

 

a).声明一个MyThread类,这个类需要继承threading.Thread(关于类的继承,不明白的小伙伴可以看Python的类,复杂吗),在init函数里面初始化一下类

b).这个类里面一个run函数,一般我们把要跑的task放在这个函数里面, 当类启动的时候,就会执行run这个函数

 

玩转Python多线程|入门篇

>>

Starting at:Sun Mar 05 20:29:40 2017

Thread-1 start loop0 at:Sun Mar 05 20:29:40 2017

Thread-2 start loop1 at:Sun Mar 05 20:29:40 2017

loop0,done at:Sun Mar 05 20:29:42 2017

loop1,done at:Sun Mar 05 20:29:44 2017

All Done At:Sun Mar 05 20:29:44 2017

 

c) .声明一个main函数,这个函数里面做了3件事,第一创建了2个MyThread类的对象,第二把这个两个子类对象放到一个列表里面threads

 

d).把threads里面的线程类一一启动,调用threads[i].start()启动线程,这时就会去调用run函数,然后用threads[i].join()等待所有的线程完成

 

4.线程的停止

线程的停止,可以用join()等待它自己结束,也可以设定成daemon(即守护线程),当主线程完成,子线程会自动销毁.那么有没有什么办法更灵活呢,比如给线程发信号,调度线程的属性或者一些高级的操作呢,有的,不过需要我们自己去构建一下.

 

玩转Python多线程|入门篇

>>

running 6 Sun Mar 05 20:56:02 2017

running 5 Sun Mar 05 20:56:03 2017

running 4 Sun Mar 05 20:56:04 2017

Terminate...

 

a).创建一个CountDownTask类,然后里面声明一个_running实例变量,用来做线程的控制

 

b).线程里面run函数里面是一个死循环,我们在while入口的地方留了两个出路,一个是_running变量,一个是n,也就是说当_running变量会false,或者n<=0的时候,线程会停止

 

c).本来线程要执行到6秒之后才会停止,我们在sleep3秒之后,就调用类的terminate函数把_running置成false, 就可以直接线程停止

 


好了Python中的并发编程-线程入门篇就讲到这里啦,是不是觉得蛮好玩的, 线程涉及的概念很多,后面会接着介绍线程间的通信 Queue,线程的同步Event,线程的锁Lock,以及多线程的爬虫等有趣的知识 .好今天的内容希望能给初学者一些启发,若有什么不懂的,也可以留言跟我探讨交流.

历史人气文章

一道Google的算法题 |Python巧妙破解

Python里的左右互搏武功 | 进程编程入门篇

九九乘法,兔子数列,杨辉三角|用Python生成器的妙解

用Python写个弹球的游戏

用Python来写一个男女相亲小程序|码农的情人节

Python入门原创文章,2016年度大盘点

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享