• 互斥锁LOCK()与RLOCK()


    资源总是有限的,程序运行如果对同一个对象进行操作,则有可能造成资源竞争,也可能导致读写混乱,此时需要引入锁。

    锁提供如下方法: 
    1.Lock.acquire([blocking])    # 上锁
    2.Lock.release()      # 解锁
    3.threading.Lock()      # 加载线程的锁对象,是一个基本的锁对象,一次只能一个锁定,其余锁请求,需等待锁释放后才能获取

    4.threading.RLock() 多重锁,在同一线程中可用被多次acquire。如果使用RLock,那么acquire和release必须成对出现, 
    调用了n次acquire锁请求,则必须调用n次的release才能在线程中释放锁对象

    例如: 
    无锁:

     1 import threading
     2 import time
     3 
     4 g_num = 0
     5 
     6 
     7 def work1(num):
     8     for i in range(num):
     9         global g_num
    10         g_num += 1
    11     print("___in work1,g_num is %d" % g_num)
    12 
    13 
    14 def work2(num):
    15     for i in range(num):
    16         global g_num
    17         g_num += 1
    18     print("___in work2,g_num is %d" % g_num)
    19 
    20 
    21 t1 = threading.Thread(target=work1, args=(1000000,))
    22 t2 = threading.Thread(target=work2, args=(1000000,))
    23 t1.start()
    24 t2.start()
    25 
    26 time.sleep(3)
    27 
    28 print("___g_num is %d" % g_num)

      运行结果:

    1 ___in work1,g_num is 1194618
    2 ___in work2,g_num is 1334899
    3 ___g_num is 1334899

    引入锁:

     1 import threading
     2 import time
     3 
     4 # 定义一个全局变量
     5 g_num = 0
     6 
     7 
     8 def work1(num):
     9     global g_num
    10     for i in range(num):
    11         # 互斥锁上锁和解锁间包含的代码越少越好
    12         mutex.acquire()
    13         g_num += 1
    14         mutex.release()
    15     print("___in work1,g_num is %d" % g_num)
    16 
    17 
    18 def work2(num):
    19     global g_num
    20     for i in range(num):
    21         mutex.acquire()
    22         g_num += 1
    23         mutex.release()
    24     print("___in work2,g_num is %d" % g_num)
    25 
    26 
    27 # 创建一个互斥锁,默认是没有上锁的
    28 mutex = threading.Lock()
    29 
    30 
    31 t1 = threading.Thread(target=work1, args=(1000000,))
    32 t2 = threading.Thread(target=work2, args=(1000000,))
    33 t1.start()
    34 t2.start()
    35 
    36 time.sleep(3)
    37 
    38 print("___g_num is %d" % g_num)

      运行结果:

    1 ___in work1,g_num is 1945701
    2 ___in work2,g_num is 2000000
    3 ___g_num is 2000000

    其中: 
      lock=threading.Lock()加载锁的方法也可以换成lock=threading.RLock()

      如果将上面的work1改为:

    1 mutex.acquire()
    2 global g_num
    3 mutexk.acquire()
    4     for i in range(num):
    5         g_num += 1
    6         mutex.release()
    7         print("___in work1,g_num is %d" % g_num)
    8         mutexk.release()

      那么: 
      lock=threading.Lock() 加载的锁,则一直处于等待中,锁等待 
      而lock=threading.RLock() 运行正常

    lock()避免死锁的解决方法:

      1.程序设置时要尽量避免(银行家算法)

      2.添加超时时间

  • 相关阅读:
    spark shuffle过程分析
    Android实现网络多线程断点续传下载
    幻世(OurDream)TM 2D图形引擎开通捐赠渠道
    MDA模型定义及扩展
    STL在迭代的过程中,删除指定的元素
    c# POST和GET方式通过server地址提交数据
    Python爬虫抓取csdn博客
    Word Ladder II
    HDU 4183 Pahom on Water(最大流SAP)
    poj1011 Sticks
  • 原文地址:https://www.cnblogs.com/zzmx0/p/12663908.html
Copyright © 2020-2023  润新知