python中lock锁和阻塞_举例讲解Python编程中对线程锁的使用

python的内置数据结构比如列表和字典等是线程安全的,但是简单数据类型比如整数和浮点数则不是线程安全的,要这些简单数据类型的通过操作,就需要使用锁。 #!/usr/bin/env python3

# coding=utf-8

import threading

shared_resource_with_lock = 0

shared_resource_with_no_lock = 0

COUNT = 100000

shared_resource_lock = threading.Lock()

####LOCK MANAGEMENT##

def increment_with_lock():

global shared_resource_with_lock

for i in range(COUNT):

shared_resource_lock.acquire()

shared_resource_with_lock += 1

shared_resource_lock.release()

def decrement_with_lock():

global shared_resource_with_lock

for i in range(COUNT):

shared_resource_lock.acquire()

shared_resource_with_lock -= 1

shared_resource_lock.release()

####NO LOCK MANAGEMENT ##

def increment_without_lock():

global shared_resource_with_no_lock

for i in range(COUNT):

shared_resource_with_no_lock += 1

def decrement_without_lock():

global shared_resource_with_no_lock

for i in range(COUNT):

shared_resource_with_no_lock -= 1

####the Main program

if __name__ == "__main__":

t1 = threading.Thread(target = increment_with_lock)

t2 = threading.Thread(target = decrement_with_lock)

t3 = threading.Thread(target = increment_without_lock)

t4 = threading.Thread(target = decrement_without_lock)

t1.start()

t2.start()

t3.start()

t4.start()

t1.join()

t2.join()

t3.join()

t4.join()

print ("the value of shared variable with lock management is %s"\

%shared_resource_with_lock)

print ("the value of shared variable with race condition is %s"\

%shared_resource_with_no_lock)

执行结果: $ ./threading_lock.py the value of shared variable with lock management is 0

the value of shared variable with race condition is 0

又如: import random

import threading

import time

logging.basicConfig(level=logging.DEBUG,

format='(%(threadName)-10s) %(message)s',

)

class Counter(object):

def __init__(self, start=0):

self.lock = threading.Lock()

self.value = start

def increment(self):

logging.debug(time.ctime(time.time()))

logging.debug('Waiting for lock')

self.lock.acquire()

try:

pause = random.randint(1,3)

logging.debug(time.ctime(time.time()))

logging.debug('Acquired lock')

self.value = self.value + 1

logging.debug('lock {0} seconds'.format(pause))

time.sleep(pause)

finally:

self.lock.release()

def worker(c):

for i in range(2):

pause = random.randint(1,3)

logging.debug(time.ctime(time.time()))

logging.debug('Sleeping %0.02f', pause)

time.sleep(pause)

c.increment()

logging.debug('Done')

counter = Counter()

for i in range(2):

t = threading.Thread(target=worker, args=(counter,))

t.start()

logging.debug('Waiting for worker threads')

main_thread = threading.currentThread()

for t in threading.enumerate():

if t is not main_thread:

t.join()

logging.debug('Counter: %d', counter.value)

执行结果: $ python threading_lock.py (Thread-1 ) Tue Sep 15 15:49:18 2015

(Thread-1 ) Sleeping 3.00

(Thread-2 ) Tue Sep 15 15:49:18 2015

(MainThread) Waiting for worker threads

(Thread-2 ) Sleeping 2.00

(Thread-2 ) Tue Sep 15 15:49:20 2015

(Thread-2 ) Waiting for lock

(Thread-2 ) Tue Sep 15 15:49:20 2015

(Thread-2 ) Acquired lock

(Thread-2 ) lock 2 seconds

(Thread-1 ) Tue Sep 15 15:49:21 2015

(Thread-1 ) Waiting for lock

(Thread-2 ) Tue Sep 15 15:49:22 2015

(Thread-1 ) Tue Sep 15 15:49:22 2015

(Thread-2 ) Sleeping 2.00

(Thread-1 ) Acquired lock

(Thread-1 ) lock 1 seconds

(Thread-1 ) Tue Sep 15 15:49:23 2015

(Thread-1 ) Sleeping 2.00

(Thread-2 ) Tue Sep 15 15:49:24 2015

(Thread-2 ) Waiting for lock

(Thread-2 ) Tue Sep 15 15:49:24 2015

(Thread-2 ) Acquired lock

(Thread-2 ) lock 1 seconds

(Thread-1 ) Tue Sep 15 15:49:25 2015

(Thread-1 ) Waiting for lock

(Thread-1 ) Tue Sep 15 15:49:25 2015

(Thread-1 ) Acquired lock

(Thread-1 ) lock 2 seconds

(Thread-2 ) Done

(Thread-1 ) Done

(MainThread) Counter: 4

acquire()中传入False值,可以检查是否获得了锁。比如: import logging

import threading

import time

logging.basicConfig(level=logging.DEBUG,

format='(%(threadName)-10s) %(message)s',

)

def lock_holder(lock):

logging.debug('Starting')

while True:

lock.acquire()

try:

logging.debug('Holding')

time.sleep(0.5)

finally:

logging.debug('Not holding')

lock.release()

time.sleep(0.5)

return

def worker(lock):

logging.debug('Starting')

num_tries = 0

num_acquires = 0

while num_acquires < 3:

time.sleep(0.5)

logging.debug('Trying to acquire')

have_it = lock.acquire(0)

try:

num_tries += 1

if have_it:

logging.debug('Iteration %d: Acquired',

num_tries)

num_acquires += 1

else:

logging.debug('Iteration %d: Not acquired',

num_tries)

finally:

if have_it:

lock.release()

logging.debug('Done after %d iterations', num_tries)

lock = threading.Lock()

holder = threading.Thread(target=lock_holder,

args=(lock,),

name='LockHolder')

holder.setDaemon(True)

holder.start()

worker = threading.Thread(target=worker,

args=(lock,),

name='Worker')

worker.start()

执行结果: $ python threading_lock_noblock.py (LockHolder) Starting

(LockHolder) Holding

(Worker ) Starting

(LockHolder) Not holding

(Worker ) Trying to acquire

(Worker ) Iteration 1: Acquired

(LockHolder) Holding

(Worker ) Trying to acquire

(Worker ) Iteration 2: Not acquired

(LockHolder) Not holding

(Worker ) Trying to acquire

(Worker ) Iteration 3: Acquired

(LockHolder) Holding

(Worker ) Trying to acquire

(Worker ) Iteration 4: Not acquired

(LockHolder) Not holding

(Worker ) Trying to acquire

(Worker ) Iteration 5: Acquired

(Worker ) Done after 5 iterations

线程安全锁 threading.RLock()

返回可重入锁对象。重入锁必须由获得它的线程释放。一旦线程获得了重入锁,同一线程可不阻塞地再次获得,获取之后必须释放。

通常一个线程只能获取一次锁: import threading

lock = threading.Lock()

print 'First try :', lock.acquire()

print 'Second try:', lock.acquire(0)

执行结果: $ python threading_lock_reacquire.py First try : True

Second try: False

使用RLock可以获取多次锁: import threading

lock = threading.RLock()

print 'First try :', lock.acquire()

print 'Second try:', lock.acquire(0)

执行结果: python threading_rlock.py First try : True

Second try: 1

再来看一个例子: #!/usr/bin/env python3

# coding=utf-8

import threading

import time

class Box(object):

lock = threading.RLock()

def __init__(self):

self.total_items = 0

def execute(self,n):

Box.lock.acquire()

self.total_items += n

Box.lock.release()

def add(self):

Box.lock.acquire()

self.execute(1)

Box.lock.release()

def remove(self):

Box.lock.acquire()

self.execute(-1)

Box.lock.release()

## These two functions run n in separate

## threads and call the Box's methods

def adder(box,items):

while items > 0:

print ("adding 1 item in the box\n")

box.add()

time.sleep(5)

items -= 1

def remover(box,items):

while items > 0:

print ("removing 1 item in the box")

box.remove()

time.sleep(5)

items -= 1

## the main program build some

## threads and make sure it works

if __name__ == "__main__":

items = 5

print ("putting %s items in the box " % items)

box = Box()

t1 = threading.Thread(target=adder,args=(box,items))

t2 = threading.Thread(target=remover,args=(box,items))

t1.start()

t2.start()

t1.join()

t2.join()

print ("%s items still remain in the box " % box.total_items)

执行结果: $ python3 threading_rlock2.py putting 5 items in the box

adding 1 item in the box

removing 1 item in the box

adding 1 item in the box

removing 1 item in the box

adding 1 item in the box

removing 1 item in the box

removing 1 item in the box

adding 1 item in the box

removing 1 item in the box

adding 1 item in the box

0 items still remain in the box

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值