013.线程-7.同步之互斥锁

7.同步之互斥锁

锁是对公共资源的一种保护机制。

例如: 12306中同时有300个人抢一张票,如果没有锁,那么我付了钱,sleep(1), 再买到票;你买的时候发现也还有票,也 sleep(1), 然后付钱,可能出现付完钱,没有票。所以加锁很有必要。

013.线程-7.同步之互斥锁_第1张图片
013.线程-7.同步之互斥锁_第2张图片

1.不加锁:

#!/usr/bin/python
# coding: utf-8
import threading
import time

tmp=0

def func():
    global tmp
    global g_lock

    for i in range(10, 20):
        tmp = i
        print " %s : tmp : %d " % (threading.currentThread().getName(), tmp)
        time.sleep(1)

if __name__ == "__main__":
    p = threading.Thread(target=func, args=())
    p.start()
    for i in range(10):
        tmp=i
        print " %s : tmp : %d " % (threading.currentThread().getName(), tmp)
    p.join()

结果:

 Thread-1 : tmp : 10  MainThread : tmp : 0 

 MainThread : tmp : 1 
 MainThread : tmp : 2 
 MainThread : tmp : 3 
 MainThread : tmp : 4 
 MainThread : tmp : 5 
 MainThread : tmp : 6 
 MainThread : tmp : 7 
 MainThread : tmp : 8 
 MainThread : tmp : 9 
 Thread-1 : tmp : 11 
 Thread-1 : tmp : 12 
 Thread-1 : tmp : 13 
 Thread-1 : tmp : 14 
 Thread-1 : tmp : 15 
 Thread-1 : tmp : 16 
 Thread-1 : tmp : 17 
 Thread-1 : tmp : 18 
 Thread-1 : tmp : 19 
[Finished in 10.1s]

2.加锁:

#!/usr/bin/python
# coding: utf-8
import threading
import time

tmp=0
g_lock = threading.Lock()

def func():
    global tmp
    global g_lock

    print '%s acquire Lock' % threading.currentThread().getName()
    g_lock.acquire()
    print '%s acquired Lock' % threading.currentThread().getName()

    for i in range(10, 20):
        tmp = i
        print " %s : tmp : %d " % (threading.currentThread().getName(), tmp)

    print '%s release Lock' % threading.currentThread().getName()
    g_lock.release()

if __name__ == "__main__":
    p = threading.Thread(target=func, args=())
    p.start()

    print '%s acquire Lock' % threading.currentThread().getName()
    g_lock.acquire()
    print '%s acquired Lock' % threading.currentThread().getName()

    for i in range(10):
        tmp=i
        print " %s : tmp : %d " % (threading.currentThread().getName(), tmp)
    print '%s release Lock' % threading.currentThread().getName()
    g_lock.release()
    p.join()

结果:

Thread-1 acquire LockMainThread acquire Lock

MainThread acquired Lock
 MainThread : tmp : 0 
 MainThread : tmp : 1 
 MainThread : tmp : 2 
 MainThread : tmp : 3 
 MainThread : tmp : 4 
 MainThread : tmp : 5 
 MainThread : tmp : 6 
 MainThread : tmp : 7 
 MainThread : tmp : 8 
 MainThread : tmp : 9 
MainThread release Lock
Thread-1 acquired Lock
 Thread-1 : tmp : 10 
 Thread-1 : tmp : 11 
 Thread-1 : tmp : 12 
 Thread-1 : tmp : 13 
 Thread-1 : tmp : 14 
 Thread-1 : tmp : 15 
 Thread-1 : tmp : 16 
 Thread-1 : tmp : 17 
 Thread-1 : tmp : 18 
 Thread-1 : tmp : 19 
Thread-1 release Lock
[Finished in 0.0s]

3.死锁

#!/usr/bin/python
# coding: utf-8
import threading
import time

tmp=0
g_lock = threading.Lock()

def func():
    global tmp
    global g_lock

    print '%s acquire Lock' % threading.currentThread().getName()
    g_lock.acquire()
    print '%s acquired Lock' % threading.currentThread().getName()
    g_lock.acquire()
    print '%s acquired again Lock' % threading.currentThread().getName()

    for i in range(10, 20):
        tmp = i
        print " %s : tmp : %d " % (threading.currentThread().getName(), tmp)

    print '%s release Lock' % threading.currentThread().getName()
    g_lock.release()

if __name__ == "__main__":
    p = threading.Thread(target=func, args=())
    p.start()

    print '%s acquire Lock' % threading.currentThread().getName()
    g_lock.acquire()
    print '%s acquired Lock' % threading.currentThread().getName()

    for i in range(10):
        tmp=i
        print " %s : tmp : %d " % (threading.currentThread().getName(), tmp)
        
    print '%s release Lock' % threading.currentThread().getName()
    g_lock.release()
    p.join()

结果:

Thread-1 acquire Lock
Thread-1 acquired Lock
MainThread acquire Lock
[Cancelled]

4.解决死锁的方案: (先释放锁)

#!/usr/bin/python
# coding: utf-8
import threading
import time

tmp=0
g_lock = threading.Lock()

def func():
    global tmp
    global g_lock

    print '%s acquire Lock' % threading.currentThread().getName()
    g_lock.acquire()
    print '%s acquired Lock' % threading.currentThread().getName()
    g_lock.acquire()
    print '%s acquired again Lock' % threading.currentThread().getName()

    for i in range(10, 20):
        tmp = i
        print " %s : tmp : %d " % (threading.currentThread().getName(), tmp)

    print '%s release Lock' % threading.currentThread().getName()
    g_lock.release()

if __name__ == "__main__":
    p = threading.Thread(target=func, args=())
    p.start()

    time.sleep(1)
    
    print '%s acquire Lock' % threading.currentThread().getName()
    g_lock.release()
    g_lock.acquire()
    print '%s acquired Lock' % threading.currentThread().getName()

    for i in range(10):
        tmp=i
        print " %s : tmp : %d " % (threading.currentThread().getName(), tmp)

    print '%s release Lock' % threading.currentThread().getName()
    g_lock.release()
    p.join()

结果:

Thread-1 acquire Lock
Thread-1 acquired Lock
MainThread acquire Lock
MainThread acquired Lock
 MainThread : tmp : 0 
 MainThread : tmp : 1 
 MainThread : tmp : 2 
 MainThread : tmp : 3 
 MainThread : tmp : 4 
 MainThread : tmp : 5 
 MainThread : tmp : 6 
 MainThread : tmp : 7 
 MainThread : tmp : 8 
 MainThread : tmp : 9 
MainThread release Lock
Thread-1 acquired again Lock
 Thread-1 : tmp : 10 
 Thread-1 : tmp : 11 
 Thread-1 : tmp : 12 
 Thread-1 : tmp : 13 
 Thread-1 : tmp : 14 
 Thread-1 : tmp : 15 
 Thread-1 : tmp : 16 
 Thread-1 : tmp : 17 
 Thread-1 : tmp : 18 
 Thread-1 : tmp : 19 
Thread-1 release Lock
[Finished in 1.0s]

5.无死锁的方案: (释放锁方案)

#!/usr/bin/python
# coding: utf-8
import threading
import time

tmp=0
g_lock = threading.Lock()

def func():
    global tmp
    global g_lock

    print '%s acquire Lock' % threading.currentThread().getName()
    g_lock.acquire()
    print '%s acquired Lock' % threading.currentThread().getName()

    for i in range(10, 20):
        tmp=i
        print " %s : tmp : %d " % (threading.currentThread().getName(), tmp)
        time.sleep(1)

    # print '%s release Lock' % threading.currentThread().getName()
    # g_lock.release()

if __name__ == "__main__":
    p = threading.Thread(target=func, args=())
    p.start()

    time.sleep(2)
    
    print '%s acquire Lock' % threading.currentThread().getName()
    g_lock.release()
    g_lock.acquire()
    print '%s acquired Lock' % threading.currentThread().getName()

    for i in range(10):
        tmp=i
        print " %s : tmp : %d " % (threading.currentThread().getName(), tmp)

    print '%s release Lock' % threading.currentThread().getName()
    g_lock.release()
    p.join()

结果:

Thread-1 acquire Lock
Thread-1 acquired Lock
 Thread-1 : tmp : 10 
 Thread-1 : tmp : 11 
MainThread acquire Lock
MainThread acquired Lock
 MainThread : tmp : 0 
 MainThread : tmp : 1 
 MainThread : tmp : 2 
 MainThread : tmp : 3 
 MainThread : tmp : 4 
 MainThread : tmp : 5 
 MainThread : tmp : 6 
 MainThread : tmp : 7 
 MainThread : tmp : 8 
 MainThread : tmp : 9 
MainThread release Lock
 Thread-1 : tmp : 12 
 Thread-1 : tmp : 13 
 Thread-1 : tmp : 14 
 Thread-1 : tmp : 15 
 Thread-1 : tmp : 16 
 Thread-1 : tmp : 17 
 Thread-1 : tmp : 18 
 Thread-1 : tmp : 19 
[Finished in 10.1s]

你可能感兴趣的:(013.线程-7.同步之互斥锁)