Py学习  »  Python

Python基础:多线程编程

Python学习交流 • 6 年前 • 422 次点击  

在python中进行多线程编程之前必须了解的问题:

1. 什么是线程?

  答:线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。

2. 什么是多线程?

  答:在单个程序中同时运行多个线程完成不同的工作,称为多线程。

3. 多线程编程的目的?

  答:多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。线程是在同一时间需要完成多项任务的时候实现的。

4. 如何再python中执行多线程编程?

  答:在python2.x的版本中提供了thread(这个模块为多线程提供了一个底层 、原始的操作[也可以成为light-weight processes 或者 tasks) — 多个控制线程共享全局数据空间。为了多线程同步,提供了简单的锁(也称呼为 mutexes 后者 binary semaphores) 。]和threading(本模块的高层线程接口构建在低层的thread模块上)两个模块用于线程操作;而在python3.x中,官方只给出了threading模块的文档,对于底层线程造作放在了_thread模块中(即不建议使用)。是故在python中使用threading模块编程即可。

喜欢的话关注收藏评论转发比心么么哒!Python学习交流群330637182内有大量的项目开发和新手教学视频五千人大群等着你来加入

例一(一个简单的双线程程序):

 注:执行上面这个程序一共花费5秒左右的时间,而如果分别调用两次run怎需要10秒(证明两个任务同时运行)。

例二(用面向对象编程实现例二,并讲解threading模块中的一些常用方法):

:建议使用例二这种编程方式,在类中,任务函数只能以run命名,参数从构造函数中传入。

  注:有时候难免会遇到一个问题,主程序的执行需要某个子线程(即使用start启动的线程,默认子线程一旦启动主程序将继续运行,两者不再有关联)的执行结果,这时使用join即可,例如例二中的t1.join()。

守护线程:一种特殊的子线程,与主线程(即本文中的主程序,由程序使用者启动)存在一种“主死仆死”的关系,即主线程意外停止或运行结束,不管守护线程是否运行完毕都得终止(非守护线程的子线程启动后与主线程没有联系,不论主线程是否还在运行,子线程不受影响),一个线程是否为守护线程继承于创建它的线程(将一个子线程设置成为守护线程可参考例二,去掉22,23行注释,则主程序结束t1,t2也结束,不会再sleep)。

在进行多线程编程时,经常会有多个线程同时对同一份数据修改,这便会导致最终得得到的数据不是预期结果。所以需要在一个线程修改数据时将数据锁定,只允许当前线程修改,当修改完成后,解锁让其他线程修改。在threading模块中使用Lock Objects解决此问题。

例三(多个线程对一个全局变量进行加1操作):

注:运行此程序,可发现一共用时10.5(0.2*50 + 0.5)秒左右,可以发现在锁定代码段程序没有并行执行。

  注:有时候需要多层加锁,这时Lock Objects已经满足不了这个需求(当Lock处于locked时,遇到下一个acquire()时会阻塞)。这时我们使用RLock Objects,它的调用同Lock Objects。

信号量:信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。

举例说明:以一个停车场的运作为例。简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。

信号量的特性:信号量是一个非负整数(车位数),所有通过它的线程/进程(车辆)都会将该整数减一(通过它当然是为了使用资源),当该整数值为零时,所有试图通过它的线程都将处于等待状态。

简单来说,当使用Lock或RLock的locked期间,没有并发执行(只unlocked后才并行);而使用Semaphore可以让有限个线程共同访问资源,它的使用也是只有acquire()和release()。

  例四(信号量的使用):

注:通过运行上面的代码,可以发现在关键代码段最多只有5个线程在同时运行。

    每调用一次acquire(),Semaphore的计数器减1;每调用一次release(),Semaphore的计数器加1,最大不超过设置的计数器初始值。

既然有了多线程编程,那么自然也就有了线程之间的交互。在python中threading模块提供了Event Objocts实现这个功能。

例五(简单的线程交互程序,演示Event Objects的使用):

作者:God_Li

源自:http://www.cnblogs.com/God-Li/p/7732407.html

声明: 文章著作权归作者所有,如有侵权,请联系小编删除


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/YRZZBF0kxW
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/3936
 
422 次点击