| 
                         如果往以上代码添加  time.sleep函数并给出不同长度的时间,可能会让这个例子更有意思。无论如何,这里的问题是,一个线程可能已经调用update_total函数并且还没有更新完成,此时另一个线程也有可能调用它并且尝试更新内容。根据操作执行顺序的不同,该值可能只被增加一次。 
让我们给这个函数添加锁。有两种方法可以实现。第一种方式是使用 try/finally,从而确保锁肯定会被释放。下面是示例: 
- import threading 
 -  
 - total = 0 
 -  
 - lock = threading.Lock 
 - def update_total(amount): 
 - """ 
 - Updates the total by the given amount 
 - """ 
 - global total 
 - lock.acquire 
 - try: 
 - total += amount 
 - finally: 
 - lock.release 
 - print (total) 
 -  
 - if __name__ == '__main__': 
 - for i in range(10): 
 - my_thread = threading.Thread( 
 - target=update_total, args=(5,)) 
 - my_thread.start 
 
  
如上,在我们做任何处理之前就获取锁。然后尝试更新 total 的值,最后释放锁并打印出 total 的当前值。事实上,我们可以使用 Python 的  with语句避免使用 try/finally 这种较为繁琐的语句: 
- import threading 
 -  
 - total = 0 
 -  
 - lock = threading.Lock 
 -  
 - def update_total(amount): 
 - """ 
 - Updates the total by the given amount 
 - """ 
 - global total 
 - with lock: 
 - total += amount 
 - print (total) 
 -  
 - if __name__ == '__main__': 
 - for i in range(10): 
 - my_thread = threading.Thread( 
 - target=update_total, args=(5,)) 
 - my_thread.start 
 
  
正如你看到的那样,我们不再需要 try/finally作为上下文管理器,而是由with语句作为替代。 
当然你也会遇到要在代码中通过多个线程访问多个函数的情况。当你第一次编写并发代码时,代码可能是这样的: 
- import threading 
 -  
 - total = 0 
 -  
 - lock = threading.Lock 
 - def do_something: 
 - lock.acquire 
 - try: 
 - print('Lock acquired in the do_something function') 
 - finally: 
 - lock.release 
 - print('Lock released in the do_something function') 
 - return "Done doing something" 
 -  
 - def do_something_else: 
 - lock.acquire 
 - try: 
 - print('Lock acquired in the do_something_else function') 
 - finally: 
 - lock.release 
 - print('Lock released in the do_something_else function') 
 - return "Finished something else" 
 -  
 - if __name__ == '__main__': 
 - result_one = do_something 
 - result_two = do_something_else 
 
  
这样的代码在上面的情况下能够正常工作,但假设你有多个线程都调用这两个函数呢。当一个线程正在运行这两个函数,然后另外一个线程也可能会修改这些数据,最后得到的就是不正确的结果。问题是,你甚至可能没有马上意识到结果错了。有什么解决办法呢?让我们试着找出答案。 
通常首先想到的就是在调用这两个函数的地方上锁。让我们试着修改上面的例子,修改成如下所示: 
- import threading 
 -  
 - total = 0 
 -  
 - lock = threading.RLock 
 - def do_something: 
 -  
 - with lock: 
 - print('Lock acquired in the do_something function') 
 - print('Lock released in the do_something function') 
 - return "Done doing something" 
 -  
 -  
 - def do_something_else: 
 - with lock: 
 - print('Lock acquired in the do_something_else function') 
 - print('Lock released in the do_something_else function') 
 - return "Finished something else" 
 -  
 - def main: 
 - with lock: 
 - result_one = do_something 
 - result_two = do_something_else 
 - print (result_one) 
 - print (result_two) 
 -  
 - if __name__ == '__main__': 
 - main 
 
                          (编辑:泰州站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |