Logo

郎哥编程

线程同步锁

2019-05-01 514

前面一节的案例提出了多线程数据同步所存在的问题,当多个Author线程修改同一个共享数据时,会发生数据覆盖或丢失的问题。

为了解决多个线程修改同一数据而发生数据覆盖或丢失的问题,Python提供了Lock对象来加保护伞,以保证数据的安全。线程调用Lock对象的acquire方法来获取锁对象(如果其他线程已经获得该锁,则当前线程需等待被释放),待资源访问完后,在调用release方法释放锁。

主线程修改代码如下:

import book
 import author
 import time
 import threading
 
 #获得lock对象
 lock = threading.Lock()
 def main():
    b = book.Book("");
    w1 = author.Author(b,"join",2,lock)
    w1.start()
    w2 = author.Author(b, "May",2,lock)
    w2.start()
    w3 = author.Author(b, "Kenny",1,lock)
    w3.start()
    w4 = author.Author(b, "Joyce",2,lock)
    w4.start()
    w5 = author.Author(b, "Alex",2,lock)
    w5.start()
    time.sleep(10)
    print("共同创作的图书内容:%s" % (b.getContent()))
 if __name__ == '__main__':
     main()

上面的代码通过threading模块的lock()方法获取Lock对象,并传入到创建的Author线程里。

Author线程的代码如下:

import threading
 import time
 import book
 # 声明图书类
 class Author(threading.Thread):
      # 作者类构造方法
     def __init__(self, inDocBook,inName,inWaitTime,inlock):
         threading.Thread.__init__(self)
         self.docbook = inDocBook
         self.name = inName
         self.waittime = inWaitTime
         self.lock = inlock
     def getDocBook(self):
         return self.docbook
     def setDocBook(self, inDocBook):
         self.docbook = inDocBook
     def run(self):
          # 中断线程
          self.lock.acquire()
          content = self.docbook.getContent() + "\n" + self.name + ":我的创作内容"
          time.sleep(self.waittime)
          self.docbook.setContent(content)
          self.lock.release()

在Author线程的run()方法中,使用锁对象对content数据进行保护,被加锁的content数据不能被其它线程修改,直至锁对象被释放后,其它线程才能获取该数据的修改权。

程序经过改造后,输出结果如下图所示:

image.png    

                                        

图 1 使用Lock对象后程序输出结果

从输出结果可以看出,创作的内容都获得了输出,这得益于Lock对象对共享数据的保护作用。Lock对象实际上是一个互斥锁,Lock对象应在主线程创建,并在主线程创建的子线程中使用。当子线程需要修改主线程的共享数据时,子线程调用Lock对象的acquire()方法获取锁对象,对共享数据加锁保护,共享数据被加锁后,其它线程将无法获得共享数据的使用权,直至子线程调用Lock对象的release()方法释放锁。


代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论