12-多线程爬虫-锁机制(threading.Lock类)

多线程存在共享全局变量的问题:

多线程都是在同一个进程中运行的,因此在进程中的全局变量所有线程都是可共享的。

这就造成一个问题,因为线程执行的顺序时无序的,有可能会造成数据错误

以上结果正常的话,应该是10000000和20000000,但因为多线程运行的不确定性,因此最后的结果可能是随机的

扩展:

启动一个线程时,线程并不会立即执行,而是等待CPU的资源调度,因次每个线程执行顺序是随机无序的,具有不确定性

# 多线程共享全局变量的问题

import threading

value = 0
value_2 = 0

def add_value():
    # 如果在函数中修改全局变量,需要global声明全局变量
    global value,value_2
    
    for x in range(100):
        value += 1
    print("{0}\tvalue的值:{1}".format(threading.current_thread().name,value))
    
    for y in range(10000000):
        value_2 += 1
    print("{0}\tvalue_2的值:{1}".format(threading.current_thread().name,value_2))
    
def main():
    for x in range(2):
        thread = threading.Thread(target=add_value)
        thread.start()

if __name__ == "__main__":
    main()

执行结果

 

锁机制和threading.Lock类:

为了解决共享全局变量的问题,threading提供了一个Lock类。

这个类可以在某个线程访问某个变量的时候加锁,其它线程此时就不能进来,直到当线程处理完后,把锁释放了,其它线程才能进来处理。

使用锁的原则:

1.把尽量少的和不耗时的代码放到锁中执行

2.代码执行完成后,要记得释放锁

# 锁机制和threading.Lock类

import threading

value = 0
value_2 = 0

# 生成一个锁对象
gLock = threading.Lock()

def add_value():
    # 如果在函数中修改全局变量,需要global声明全局变量
    global value,value_2
    
    # 加锁
    gLock.acquire()
    
    for x in range(100):
        value += 1
    print("{0}\tvalue的值:{1}".format(threading.current_thread().name,value))
    
    for y in range(10000000):
        value_2 += 1
    print("{0}\tvalue_2的值:{1}".format(threading.current_thread().name,value))
    
    # 释放锁
    gLock.release()
    
def main():
    for x in range(2):
        thread = threading.Thread(target=add_value)
        thread.start()

if __name__ == "__main__":
    main()

执行结果

 

 

 

 

 

posted @ 2021-04-15 20:08  马铃薯1  阅读(232)  评论(0编辑  收藏  举报