|
13 | 13 |
|
14 | 14 | .. image:: ../images/deadlock.png
|
15 | 15 |
|
| 16 | +为了简化问题,我们设有两个并发的线程( **线程A** 和 **线程B** ),需要 **资源1** 和 **资源2** .假设 **线程A** 需要 **资源1** , **线程B** 需要 **资源2** .在这种情况下,两个线程都使用各自的锁,目前为止没有冲突。现在假设,在双方释放锁之前, **线程A** 需要 **资源2** 的锁, **线程B** 需要 **资源1** 的锁,没有资源线程不会继续执行。鉴于目前两个资源的锁都是被占用的,而且在对方的锁释放之前都处于等待且不释放锁的状态。这是死锁的典型情况。所以如上所说,使用锁来解决同步问题是一个可行却存在潜在问题的方案。 |
| 17 | + |
| 18 | +本节中,我们描述了Python的线程同步机制, ``lock()`` 。通过它我们可以将共享资源某一时刻的访问限制在单一线程或单一类型的线程上,线程必须得到锁才能使用资源,并且之后必须允许其他线程使用相同的资源。 |
| 19 | + |
| 20 | +|how| |
| 21 | +----- |
| 22 | + |
| 23 | +下面的例子展示了如何通过 ``lock()`` 管理线程。在下面的代码中,我们有两个函数: ``increment()`` 和 ``decrement()`` 。第一个函数对共享资源执行加1的操作,另一个函数执行减1.两个函数分别使用线程封装。除此之外,每一个函数都有一个循环重复执行操作。我们想要保证,通过对共享资源的管理,执行结果是共享资源最后等于初始值0. |
| 24 | + |
| 25 | +代码如下: :: |
| 26 | + |
| 27 | + # -*- coding: utf-8 -*- |
| 28 | + |
| 29 | + import threading |
| 30 | + |
| 31 | + shared_resource_with_lock = 0 |
| 32 | + shared_resource_with_no_lock = 0 |
| 33 | + COUNT = 100000 |
| 34 | + shared_resource_lock = threading.Lock() |
| 35 | + |
| 36 | + # 有锁的情况 |
| 37 | + def increment_with_lock(): |
| 38 | + global shared_resource_with_lock |
| 39 | + for i in range(COUNT): |
| 40 | + shared_resource_lock.acquire() |
| 41 | + shared_resource_with_lock += 1 |
| 42 | + shared_resource_lock.release() |
| 43 | + |
| 44 | + def decrement_with_lock(): |
| 45 | + global shared_resource_with_lock |
| 46 | + for i in range(COUNT): |
| 47 | + shared_resource_lock.acquire() |
| 48 | + shared_resource_with_lock -= 1 |
| 49 | + shared_resource_lock.release() |
| 50 | + |
| 51 | + ####NO LOCK MANAGEMENT ## |
| 52 | + def increment_without_lock(): |
| 53 | + global shared_resource_with_no_lock |
| 54 | + for i in range(COUNT): |
| 55 | + shared_resource_with_no_lock += 1 |
| 56 | + |
| 57 | + def decrement_without_lock(): |
| 58 | + global shared_resource_with_no_lock |
| 59 | + for i in range(COUNT): |
| 60 | + shared_resource_with_no_lock -= 1 |
| 61 | + |
| 62 | + if __name__ == "__main__": |
| 63 | + t1 = threading.Thread(target = increment_with_lock) |
| 64 | + t2 = threading.Thread(target = decrement_with_lock) |
| 65 | + t3 = threading.Thread(target = increment_without_lock) |
| 66 | + t4 = threading.Thread(target = decrement_without_lock) |
| 67 | + t1.start() |
| 68 | + t2.start() |
| 69 | + t3.start() |
| 70 | + t4.start() |
| 71 | + t1.join() |
| 72 | + t2.join() |
| 73 | + t3.join() |
| 74 | + t4.join() |
| 75 | + print ("the value of shared variable with lock management is %s" % shared_resource_with_lock) |
| 76 | + print ("the value of shared variable with race condition is %s" % shared_resource_with_no_lock) |
| 77 | + |
| 78 | +代码执行的结果如下: |
| 79 | + |
| 80 | +.. image:: ../images/Page-65-Image-9.png |
| 81 | + |
| 82 | +可以看出,如果有锁来管理线程的话,我们会得到正确的结果。这里要注意,没有锁的情况下并不一定会得到错误的结果,但是重复执行多次,总会出现错误的结果。而有锁的情况结果总会是正确的。 |
| 83 | + |
| 84 | +|work| |
| 85 | +------ |
| 86 | + |
16 | 87 |
|
0 commit comments