共享变量
- 当多个线程同时访问一个变量的时候,会产生共享变量问题
- 解决方法:锁\信号灯
- 锁:Lock
- 是一个标志,表示一个线程占用一些资源
- 使用方法:
- 上锁
- 受用共享资源
- 取消锁,释放锁
- 锁:Lock
# 共享变量问题案例
import threading
sum = 0
loopSum = 10000
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("Staring.......{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))
Staring.......0
Done.......0
锁的定义
lock = threading.Lock()
def XXX():
#上锁
lock.acquire()
#函数体
#释放锁
lock.release()
- 锁谁?
- 那个资源需要多个线程共享,锁哪个
- 解释:
- 锁其实不是锁住哪个,而是一个令牌,拥有令牌的线程有权限使用相关的共享资源
线程安全
-
如果一个资源\变量,他对于多线程来讲,不用加锁也不会引起任何问题,则称为线程安全
-
线程不安全变量类型:
- list
- set
- dict
-
线程安全变量类型:
- queue
生产者消费问题
- 一个模型,可以用来搭建消息队列
import threading
import time
import queue
class Producer(threading.Thread):
def run(self):
global queue
count = 0
while True:
#qsize 返回queue的长度
if queue.qsize() < 1000:
for i in range(100):
count = count + 1
msg = "生产了产品"+str(count)
#put是往queue中放入一个值
queue.put(msg)
print(msg)
time.sleep(0.5)
class Consumer(threading.Thread):
def run(self):
global queue
while True:
if queue.qsize()>100:
for i in range(3):
msg = self.name + '消费了'+ queue.get()
print(msg)
time.sleep(1)
if __name__ == '__main__':
queue = queue.Queue()
# 初始队列.在队列中存放500个消息
for i in range(500):
queue.put("初始产品:"+str(i))
# 定义两个生产者
for i in range(2):
p = Producer()
p.start()
# 定义5个消费者
for i in range(5):
c = Consumer()
c.start()
死锁问题
锁的等待时间问题
- lock_2.acquire(timeout = 等待时间)
semphore
- 允许一个资源最多由几个多线程同事使用
- https://www.cnblogs.com/renpingsheng/p/7202818.html
threading.Timer
- 在指定秒数之后执行指定的func
可重入锁
- 一个锁,可以被一个线程多次申请
- 主要解决递归调用的时候,需要申请锁的情况
- lock = threading.RLock()
- https://www.cnblogs.com/i-honey/p/8067503.html
网友评论