详细讲解Python线程应用程序操作

开发 后端
在进行调用Python线程应用程序时,会在_limbo中记录线程,然后通过thread.start_new_thread创建原生线程,把线程创建的过程为bootstrap。

Python线程应用程序中的提供的低级的线程控制工具有thread module,一些为了简化多线程应用的开发程序员,用Python语言在thread的基础上构建了一个高级的线程控制库——threading。

在这一节中,我们将剖析threading的具体实现。在剖析threading的具体实现之前,我们先来看看threading是如何使用的。我们知道通过threading.Thread创建多线程,有两个阶段,第一阶段是调用threading.Thread.start,而第二阶段是在threading.Thread.start中调用threading.Thread.run。

当处于第一阶段时,还没有调用thread.start_new_thread创建原生子线程,这时候线程记录在_limbo中。由于没有创建子线程,所以现在没有线程id,记录的方式为_limbo[thread] = thread。

在第二阶段,已经成功地调用thread. start_new_thread创建了原生子线程,这时将从_limbo中删除子线程,而将子线程记录到_active中,记录的方式为_active[thread_id] = thread。可见。

Python这两个dict分别维护了已经创建和等待创建的子线程集合。对这两个dict的访问_active_limbo_ lock的保护之下进行。在threading module中,提供了列举当前所有子线程的操作:threading. enumerate。这个操作很简单,就是将_active和_limbo中维护的线程集合的信息输出。

在thread module中,Python提供了用户级的线程同步工具:Lock对象。而在threading module中,Python提供了不同的用于线程同步的工具。以简化Python线程应用程序序。这些threading中的线程同步工具实际上都是建立在thread所提供的Lock对象的基础上的。

通过调用threading.Lock,我们就可以创建一个thread中的Lock对象,如前面所描述的,在这个对象上,我们可以进行acquire、release等操作。在threading中的其他线程同步工具都是在这个Lock对象的基础上,下面我们将对这些线程同步工具做一个概述性的介绍,具体的实现请读者参阅threading.py。

RLock对象是Lock对象的一个变种,其内部维护着一个Lock对象,但是它是一种可重入的Lock。一般地,对于Lock对象而言,如果一个线程连续两次进行acquire操作。那么由于第一次acquire之后没有release,第二次acquire将挂起线程,这将直接导致Lock对象永远不会release,因此线程死锁。

RLock对象允许一个线程多次对其进行acquire操作,因为在其内部通过一个counter变量维护着线程acquire的次数。而且每一次的acquire操作必须有一个release操作与之对应,在所有的release操作都完成之后,别的线程才能申请该RLock对象。

Python线程应用程序对象是对Lock对象的包装,在创建Condition对象时,其构造函数需要一个Lock对象作为参数,如果没有这个Lock对象参数,Condition将在内部自行创建一个Rlock对象。

在Condition对象上,当然也可以调用acquire和release操作,因为内部的Lock对象本身就支持这些操作。但是Condition的价值在于其提供的wait和notify的语义。假设有Condition对象C,当线程A调用C.wait()时,线程A将释放C中的Lock对象,并进入阻塞状态。

直到有别的线程调用C.notify(),A才会重新通过acquire申请C中的Lock对象,并退出wait操作。Semaphore对象内部维护着一个Condition对象,对于管理一组共享资源非常有用。Lock对象可以保护一个共享资源,但是假如我们有一个共享资源池,其中有5个共享资源A。

这意味着可以有5个线程同时自由地访问这些资源,然而如果使用Lock来对共享资源进行保护的话,所有的线程都将互斥,这使得有4个资源A被浪费了。Semaphore正是在Condition的基础上实现的对共享资源池进行保护的线程同步机制。Semaphore提供了两个操作:acquire和release,都具有与Lock相同的语义。

当线程调用Semaphore. acquire时,如果共享资源池中还有剩余的A时,线程就会继续执行;而如果资源池中已经没有任何资源存在了,线程就会将自身挂起,直到别的线程调用Semaphore.release释放一个资源。

与Semaphore类似,Event对象实际上也是对Condition对象的一种包装,只是提供了独有的set和wait语义。Event类的代码很简单,有兴趣的读者可以参考threading.py。在thread3.py中我们看到,threading中一个关键的组件是threading.Thread,在这一节中我们来看一看它的具体实现。在threading.Thread的实现中,你会发现我们前面提到的许多机制。

【编辑推荐】

  1. 有关Python系统文件进行介绍指导
  2. 如何正确的使用Python函数
  3. 对Python 构建工具进行详细介绍分析
  4. PythonAndroid浅析Python优势所在
  5. 如何使用Python模块解析配置文件?
责任编辑:chenqingxiang 来源: 博客园
相关推荐

2009-09-27 17:23:16

Hibernate应用

2009-10-10 13:56:44

IIS应用程序VB开发

2009-10-27 12:20:06

VB.NET多线程应用

2011-07-20 15:58:58

iPhone 应用程序 生命周期

2009-12-25 10:39:49

WPF应用程序关闭

2010-03-03 17:56:44

Android应用程序

2021-09-26 08:30:31

Python应用程序代码

2011-07-26 11:13:15

iPhone PXL

2009-12-21 11:22:37

Linux网络操作命令

2011-07-19 10:56:15

iPhone 控制器 视图

2011-07-19 11:12:07

iPhone 控制器

2011-07-19 10:42:41

iPhone 应用程序 模型

2010-02-02 15:37:11

2010-02-26 11:08:29

Python应用程序

2011-12-07 12:01:31

ibmdw

2010-02-01 14:05:03

2010-02-22 17:46:57

Python应用程序

2024-06-24 10:53:23

2009-10-09 17:01:32

VB.NET多线程

2011-07-12 10:59:41

JAVA多线程
点赞
收藏

51CTO技术栈公众号