首页 > 代码库 > Python 学习笔记 - 线程(2)

Python 学习笔记 - 线程(2)

前面学习了线程基本的概念和创建线程的两种方法,现在看看多线程如何处理竞争条件(racing condition)的问题。


比如说,下面的例子中 我使用了第二种创建的方式,自定义一个类,继承Thread类,然后自定义run()来执行我的方法。在这个run方法里面,每次都对全局变量加1


在主线程里面,他调用一个自己定义的函数,在这个函数里面创建了5000个线程;每个线程都加入一个列表,然后对每个对象都使用join,这是确保主线程等着直到所有子线程完成。最后输出结果


import time
import threading
some_var = 0
class IncrementThread(threading.Thread):
    def run(self):
        #we want to read a global variable
        #and then increment it
        global some_var
        read_value = some_var
        print ("some_var in %s is %d" % (self.name, read_value))
        some_var = read_value + 1
        print ("some_var in %s after increment is %d" % (self.name, some_var))
def use_increment_thread():
    threads = []
    start=time.time()
    for i in range(5000):
        t = IncrementThread()
        threads.append(t)
        t.start()
    for t in threads:
        t.join()
    print("Total time %s"%(time.time()-start))
    print ("After 5000 modifications, some_var should have become 5000")
    print ("After 5000 modifications, some_var is %d" % (some_var,))
use_increment_thread()

------------------

Total time 1.7780036926269531
After 5000 modifications, some_var should have become 5000
After 5000 modifications, some_var is 4987


可以看见结果并不是5000,这是为啥呢? 如果查看过程,会发现有些线程刚刚获取了一个值,还未来得及处理,执行的权力就转交给了另外一个线程,这样就导致计数错误。为了确保每一个线程都成功的执行了他应该执行的代码,我们可以加一把锁。

some_var in Thread-1524 is 1523
some_var in Thread-1524 after increment is 1524
some_var in Thread-1525 is 1524
some_var in Thread-1526 is 1524
some_var in Thread-1526 after increment is 1525
some_var in Thread-1527 is 1525


下面是修订过的代码,通过使用Lock()函数,我们在执行代码前acquire(),之后release(),在当前线程完成这段代码之前,其他的线程不可以执行相同的操作。

some_var = 0
lock=threading.Lock()
class IncrementThread(threading.Thread):
    def run(self):
        #we want to read a global variable
        #and then increment it
        global some_var
        lock.acquire()
        read_value = some_var
        print ("some_var in %s is %d" % (self.name, read_value))
        some_var = read_value + 1
        print ("some_var in %s after increment is %d" % (self.name, some_var))
        lock.release()
def use_increment_thread():
    threads = []
    start=time.time()
    for i in range(5000):
        t = IncrementThread()
        threads.append(t)
        t.start()
    for t in threads:
        t.join()
    print("Total time %s"%(time.time()-start))
    print ("After 5000 modifications, some_var should have become 5000")
    print ("After 5000 modifications, some_var is %d" % (some_var,))
use_increment_thread()
---------------
Total time 1.6369926929473877
After 5000 modifications, some_var should have become 5000
After 5000 modifications, some_var is 5000


本文出自 “麻婆豆腐” 博客,请务必保留此出处http://beanxyz.blog.51cto.com/5570417/1866269

Python 学习笔记 - 线程(2)