同一个进程的内多个线程可以同时访问和修改同一个数据, 这样的数据我们一般称之为共享资源.

资源共享的问题

下面我们用多个线程去访问同一个资源:

from threading import *
import time

num = 100  # 定义一个变量, 表示共享资源


def foo():
    global num
    for i in range(100):
        if num > 0:  # num值不允许是负数
            time.sleep(0.3)
            num = num - 1
            print(current_thread().name, num)


for i in range(6):
    t = Thread(target=foo, name="子线程 %d" % i)
    t.start()

说明:

虽然我们中代码中限制了num不会小于0,但是由于多个线程同时修改了共享资源, 导致出现了不应该出现的合理情况.

原因:

假设现在num == 1, 假设线程0 的if运行之后, 进入了线程休眠,然后线程1(或者其他线程)也进来了, 那么num仍然是1, 然后休眠.

这个时候线程0休眠结束了, 把num变成0. 然后线程0就会结束了.这个时候线程1休眠结束了, 会从刚才休眠的地方继续执行, 然后把num变成了-1 ....

Lock对象

如何解决上面的问题?

如果有线程的if为true, 在这个线程离开if语句之前, 则不应该有其他线程进到if语句中.

python提供了一种叫做Lock的锁来实现这种需求.

from threading import *
import time

num = 100  # 定义一个变量, 表示共享资源
# 创建一个锁, 用这把锁去锁定共享资源,只有抢到这个把锁的线程才可以修改共享资源
lock = Lock()

```python
def foo():
    global num, lock

    for i in range(100):
        lock.acquire()  # 获取到锁
        try:
            if num > 0:  # num值不允许是负数
                num = num - 1
                print(current_thread().name, num)
        finally:
            lock.release()  # 一定要释放锁, 所以把释放锁的代码放在finally中


for i in range(6):
    t = Thread(target=foo, name="子线程 %d" % i)
    t.start()

Copyright © 李振超 2018 all right reserved,powered by Gitbook
该文件最后修订时间: 2018-02-25 07:12:09

results matching ""

    No results matching ""