您好,欢迎访问一九零五行业门户网

举例Python编程中对线程锁

python的threading模块中提供了多种锁的相关方法,python的多线程不能同时执行,因而锁的使用非常关键,下面我们就来举例讲解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
更多举例python编程中对线程锁。
其它类似信息

推荐信息