Python多线程编程(四):使用Lock互斥锁

 更新时间:2015年04月05日 11:32:30   投稿:junjie  
这篇文章主要介绍了Python多线程编程(四):使用Lock互斥锁,本文讲解了互斥锁概念、同步阻塞、代码示例等内容,需要的朋友可以参考下

前面已经演示了Python:使用threading模块实现多线程编程二两种方式起线程Python:使用threading模块实现多线程编程三threading.Thread类的重要函数,这两篇文章的示例都是演示了互不相干的独立线程,现在我们考虑这样一个问题:假设各个线程需要访问同一公共资源,我们的代码该怎么写?

复制代码 代码如下:

'''
Created on 2012-9-8
 
@author: walfred
@module: thread.ThreadTest3
''' 
import threading 
import time 
 
counter = 0 
 
class MyThread(threading.Thread): 
    def __init__(self): 
        threading.Thread.__init__(self) 
 
    def run(self): 
        global counter 
        time.sleep(1); 
        counter += 1 
        print "I am %s, set counter:%s" % (self.name, counter) 
 
if __name__ == "__main__": 
    for i in range(0, 200): 
        my_thread = MyThread() 
        my_thread.start()

解决上面的问题,我们兴许会写出这样的代码,我们假设跑200个线程,但是这200个线程都会去访问counter这个公共资源,并对该资源进行处理(counter += 1),代码看起来就是这个样了,但是我们看下运行结果:

复制代码 代码如下:

I am Thread-69, set counter:64
I am Thread-73, set counter:66I am Thread-74, set counter:67I am Thread-75, set counter:68I am Thread-76, set counter:69I am Thread-78, set counter:70I am Thread-77, set counter:71I am Thread-58, set counter:72I am Thread-60, set counter:73I am Thread-62, set counter:74I am Thread-66,set counter:75I am Thread-70, set counter:76I am Thread-72, set counter:77I am Thread-79, set counter:78I am Thread-71, set counter:78

打印结果我只贴了一部分,从中我们已经看出了这个全局资源(counter)被抢占的情况,问题产生的原因就是没有控制多个线程对同一资源的访问,对数据造成破坏,使得线程运行的结果不可预期。这种现象称为“线程不安全”。在开发过程中我们必须要避免这种情况,那怎么避免?这就用到了我们在综述中提到的互斥锁了。

互斥锁概念

Python编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为” 互斥锁” 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。在Python中我们使用threading模块提供的Lock类。

我们对上面的程序进行整改,为此我们需要添加一个互斥锁变量mutex = threading.Lock(),然后在争夺资源的时候之前我们会先抢占这把锁mutex.acquire(),对资源使用完成之后我们在释放这把锁mutex.release()。代码如下:

复制代码 代码如下:

'''
Created on 2012-9-8
 
@author: walfred
@module: thread.ThreadTest4
''' 
 
import threading 
import time 
 
counter = 0 
mutex = threading.Lock() 
 
class MyThread(threading.Thread): 
    def __init__(self): 
        threading.Thread.__init__(self) 
 
    def run(self): 
        global counter, mutex 
        time.sleep(1); 
        if mutex.acquire(): 
            counter += 1 
            print "I am %s, set counter:%s" % (self.name, counter) 
            mutex.release() 
 
if __name__ == "__main__": 
    for i in range(0, 100): 
        my_thread = MyThread() 
        my_thread.start()

同步阻塞

当一个线程调用Lock对象的acquire()方法获得锁时,这把锁就进入“locked”状态。因为每次只有一个线程1可以获得锁,所以如果此时另一个线程2试图获得这个锁,该线程2就会变为“blo同步阻塞状态。直到拥有锁的线程1调用锁的release()方法释放锁之后,该锁进入“unlocked”状态。线程调度程序从处于同步阻塞状态的线程中选择一个来获得锁,并使得该线程进入运行(running)状态。

进一步考虑

通过对公共资源使用互斥锁,这样就简单的到达了我们的目的,但是如果我们又遇到下面的情况:

遇到锁嵌套的情况该怎么办,这个嵌套是指当我一个线程在获取临界资源时,又需要再次获取;
如果有多个公共资源,在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源;

上述这两种情况会直接造成程序挂起,即死锁,下面我们会谈死锁及可重入锁RLock。

相关文章

  • Python 调用VC++的动态链接库(DLL)

    Python 调用VC++的动态链接库(DLL)

    Python下调用VC++的动态链接库的脚本
    2008-09-09
  • python和php哪个容易学

    python和php哪个容易学

    在本篇文章里小编给大家整理的是一篇关于python和php哪个学起来简单的相关文章,需要的朋友们可以参考下。
    2020-06-06
  • 如何更优雅地写python代码

    如何更优雅地写python代码

    这篇文章主要介绍了如何更优雅地写python代码,我们写代码,往往还是按照其它语言的思维习惯来写,那样的写法不仅运行速度慢,代码读起来也费尽,给人一种拖泥带水的感觉,需要的朋友可以参考下
    2019-07-07
  • Python base64编码解码实例

    Python base64编码解码实例

    这篇文章主要介绍了Python base64编码解码实例,本文直接给出实例代码,使用也很简单,需要的朋友可以参考下
    2015-06-06
  • 基于Python实现原创程序猿乘风破浪小游戏

    基于Python实现原创程序猿乘风破浪小游戏

    最近学习了一丁点Pygame技能,感觉有点上头,一波操作创作“程序猿乘风破浪”游戏一款,文中的示例代码讲解详细,希望大家能够喜欢
    2023-02-02
  • python下PyGame的下载与安装过程及遇到问题

    python下PyGame的下载与安装过程及遇到问题

    这篇文章主要介绍了python下PyGame的下载与安装过程及遇到问题,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • 浅析Python中的join()方法的使用

    浅析Python中的join()方法的使用

    这篇文章主要介绍了Python中的join()方法的使用,是Python入门中的基础知识,需要的朋友可以参考下
    2015-05-05
  • python缺失值填充方法示例代码

    python缺失值填充方法示例代码

    常见的数据缺失填充方式分为很多种,比如删除法、均值法、回归法、KNN、MICE、EM等,下面这篇文章主要给大家介绍了关于python缺失值填充方法的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • Python Flask框架实现简单加法工具过程解析

    Python Flask框架实现简单加法工具过程解析

    这篇文章主要介绍了Python Flask框架实现简单加法工具过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • django 微信网页授权登陆的实现

    django 微信网页授权登陆的实现

    这篇文章主要介绍了django 微信网页授权登陆的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07

最新评论