共享变量

  • 共享变量: 当多个线程同时访问一个变量的时候,会产生共享变量的问题
  • 案例:
import threading
sum = 0
loopSum = 1000000

def myAdd():
   global  sum, loopSum
   for i in range(1, loopSum):
       sum += 1

def myMinu():
   global  sum, loopSum
   for i in range(1, loopSum):
       sum -= 1

if __name__ == '__main__':
   print("Starting ....{0}".format(sum))
   # 开始多线程的实例,看执行结果是否一样
   t1 = threading.Thread(target=myAdd, args=())
   t2 = threading.Thread(target=myMinu, args=())

   t1.start()
   t2.start()

   t1.join()
   t2.join()

   print("Done .... {0}".format(sum))

  • 解决方法:锁,信号灯,....
  • 锁(Lock):
    • 是一个标志,表示一个线程在占用一些资源
    • 使用方法:
      • 上锁
      • 使用共享资源,放心的用
      • 取消锁,释放锁
lock = threading.Lock()
def myAdd():
	 global  sum, loopSum

    for i in range(1, loopSum):
        # 上锁,申请锁
        lock.acquire()
        sum += 1
        # 释放锁
        lock.release()
  • 锁谁: 哪个资源需要多个线程共享,锁哪个

    • 理解锁:锁其实不是锁住谁,而是一个令牌
  • 线程安全问题:

    • 如果一个资源/变量,他对于多线程来讲,不用加锁也不会引起任何问题(只有一个线程使用或多个使用但是其他都是只读),则称为线程安全
    • 线程不安全变量类型: list, set, dict
    • 线程安全变量类型: queue
  • 生产者消费者问题

    • 一个模型,一般用来搭建消息队列(message queue),数据产生的速度和消费的速度不对等
    • queue是一个用来存放变量的数据结构,特点是先进先出,内部元素排队,可以理解成一个特殊的list
  • 死锁问题, 案例14,多注意代码可能导致死锁的地方。

  • 锁的等待时间:申请锁超时的时间--lock.acquire(timeout=4)

  • semphore

    • 允许一个资源最多由几个多线程同时使用
# 参数定义最多几个线程同时使用资源
semaphore = threading.Semaphore(3)
```
- threading.Timer
    
     - Timer是利用多线程,在指定时间后启动一个功能
     -  t = threading.Timer(6, func)    
- 可重入锁
     - 一个锁,可以被一个线程多次申请
     - 主要解决递归调用的时候,需要申请锁的情况
     - mutelock = threading.RLock()