Python-threading(二)

版权声明:此博文为博主原创,未经允许不得私自转载! https://blog.csdn.net/pansaky/article/details/89149112

在第一篇文章中,主要学习了一些概念性的东东,这里还是想把threading提供的实例用法好好琢磨一下,方便以后使用的时候能够正确理解并运用这些方法。

threading模块中Thread类实例提供的方法及用途上一篇基本上说清楚了,接着往下看看其它实例

class threading.Lock
The class implementing primitive lock objects. Once a thread has acquired a lock, subsequent attempts to acquire it block, until it is released; any thread may release it.

Note that Lock is actually a factory function which returns an instance of the most efficient version of the concrete Lock class that is supported by the platform.

acquire(blocking=True, timeout=-1)
Acquire a lock, blocking or non-blocking.


release()
Release a lock. This can be called from any thread, not only the thread which has acquired the lock.

When the lock is locked, reset it to unlocked, and return. If any other threads are blocked waiting for the lock to become unlocked, allow exactly one of them to proceed.

When invoked on an unlocked lock, a RuntimeError is raised.

There is no return value.

RLock Objects
A reentrant lock is a synchronization primitive that may be acquired multiple times by the same thread. Internally, it uses the concepts of “owning thread” and “recursion level” in addition to the locked/unlocked state used by primitive locks. In the locked state, some thread owns the lock; in the unlocked state, no thread owns it.


class threading.RLock
This class implements reentrant lock objects. A reentrant lock must be released by the thread that acquired it. Once a thread has acquired a reentrant lock, the same thread may acquire it again without blocking; the thread must release it once for each time it has acquired it.

acquire(blocking=True, timeout=-1)
Acquire a lock, blocking or non-blocking.


release()

以上是官方对threading模块中lock  锁的解释,关于锁的使用主要有两个类实例,都提供了锁的acquire()和release()方法。简言之就是获取锁定和释放锁。看下示例了解下具体用法

这个例子比较经典,拿过来用一哈:

同步锁

 

用num -= 1则最终结果没问题,这是因为完成这个操作太快了,在线程切换时间内。用中间变量temp进行赋值时出现问题,这是因为100个线程,每一个都没有执行完就就行了切换,因此最终得到的不是0。

多个线程同时操作同一个共享资源,所以导致冲突,这种情况就需要用同步锁来解决。

 import time
 import threading
  
 def addNum():
     global num #在每个线程中都获取这个全局变量
     # num-=1
 
     temp=num
     print('--get num:',num )
     #time.sleep(0.1)
     num =temp-1 #对此公共变量进行-1操作
 
 
 num = 100  #设定一个共享变量
 thread_list = []
 for i in range(100):
     t = threading.Thread(target=addNum)
     t.start()
     thread_list.append(t)
 
 for t in thread_list: #等待所有线程执行完毕
     t.join()
 
 print('final num:', num )
 import time
 import threading
 
 def addNum():
     global num #在每个线程中都获取这个全局变量
     # num-=1
     lock.acquire()    #加同步锁
     temp=num
     print('--get num:',num )
     #time.sleep(0.1)
     num =temp-1 #对此公共变量进行-1操作
     lock.release()    #解锁
 
 num = 100  #设定一个共享变量
 thread_list = []
 lock=threading.Lock()  #创建lock对象
 
 for i in range(100):
     t = threading.Thread(target=addNum)
     t.start()
     thread_list.append(t)
 
 for t in thread_list: #等待所有线程执行完毕
     t.join()      #所有线程执行完后主程序才能结束
 
 print('final num:', num )

GIL与同步锁的作用对比:

GIL:同一时刻只能有一个线程进入解释器。

同步锁:同一时刻,保证只有一个线程被执行,在局部保证操作共享资源时不会发生冲突。

十一、线程死锁和递归锁

所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。 由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁。

实例:

import threading,time
 
class myThread(threading.Thread):
    def doA(self):
        lockA.acquire()
        print(self.name,"gotlockA",time.ctime())
        time.sleep(3)
        lockB.acquire()
        print(self.name,"gotlockB",time.ctime())
        lockB.release()
        lockA.release()

    def doB(self):
        lockB.acquire()
        print(self.name,"gotlockB",time.ctime())
        time.sleep(2)
        lockA.acquire()
        print(self.name,"gotlockA",time.ctime())
        lockA.release()
        lockB.release()
    def run(self):
        self.doA()
        self.doB()
if __name__=="__main__":
 
    lockA=threading.Lock()
    lockB=threading.Lock()
    threads=[]
    for i in range(5):
        threads.append(myThread())
    for t in threads:
        t.start()
    for t in threads:
        t.join()#等待线程结束,后面再讲。

死锁解决办法:

使用递归锁,创建Rlock对象,在需要加锁时使用

1 lockA=threading.Lock()
2 lockB=threading.Lock()


lock = threading.Rlock()

猜你喜欢

转载自blog.csdn.net/pansaky/article/details/89149112
今日推荐