共享变量
- 当多个线程同时访问同一个变量的时候,会产生共享变量的问题
- 解决变量
- 锁,信号灯
- 锁(Lock):
- 是一个标志,表示一个线程在占用一些资源
- 使用方法
- 上锁
- 使用共享资源,放心使用
- 取消锁,释放锁
- 锁谁:哪个资源需要多个线程共享,锁哪个
- 理解锁:锁其实不是锁住谁,而是一个令牌
- 线程安全问题:
- 如果一个变量/资源,他对于多线程来讲,不用加锁也不会引起任何问题,则成为线程安全
- 线程不安全变量类型:list, set, dict
- 线程安全变量类型:queue
- 生产者消费者问题
- 一个模型,可以用来搭建消息队列
- queue是一个用来存放变量的数据结构,特点是先进先出,内部元素排队,可以理解成一个特殊的list
import threadingsum = 0
loopSum = 1000000def myAdd():global sum, loopSumfor i in range(1, loopSum):sum += 1def myMinu():global sum, loopSumfor i in range(1, loopSum):sum -= 1if __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))
Starting ....0
Done .... -11539
import threadingsum = 0
loopSum = 1000000lock = threading.Lock()def myAdd():global sum, loopSumfor i in range(1, loopSum):lock.acquire()sum += 1lock.release()def myMinu():global sum, loopSumfor i in range(1, loopSum):lock.acquire()sum -= 1lock.release()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))
Starting ....0
Done .... 0
import threading
import time
import queueclass Producer(threading.Thread):def run(self):global queuecount &#61; 0while True:if queue.qsize() < 1000:for i in range(100):count &#61; count &#43;1msg &#61; &#39;生成产品&#39;&#43;str(count)queue.put(msg)print(msg)time.sleep(0.5)class Consumer(threading.Thread):def run(self):global queuewhile True:if queue.qsize() > 100:for i in range(3):msg &#61; self.name &#43; &#39;消费了 &#39;&#43;queue.get()print(msg)time.sleep(1)if __name__ &#61;&#61; &#39;__main__&#39;:queue &#61; queue.Queue()for i in range(500):queue.put(&#39;初始产品&#39;&#43;str(i))for i in range(2):p &#61; Producer() p.start()for i in range(5): c &#61; Consumer()c.start()
import threading
import timelock_1 &#61; threading.Lock()
lock_2 &#61; threading.Lock()def func_1():print("func_1 starting.........")lock_1.acquire()print("func_1 申请了 lock_1....")time.sleep(2)print("func_1 等待 lock_2.......")lock_2.acquire()print("func_1 申请了 lock_2.......")lock_2.release()print("func_1 释放了 lock_2")lock_1.release()print("func_1 释放了 lock_1")print("func_1 done..........")def func_2():print("func_2 starting.........")lock_2.acquire()print("func_2 申请了 lock_2....")time.sleep(4)print("func_2 等待 lock_1.......")lock_1.acquire()print("func_2 申请了 lock_1.......")lock_1.release()print("func_2 释放了 lock_1")lock_2.release()print("func_2 释放了 lock_2")print("func_2 done..........")if __name__ &#61;&#61; "__main__":print("主程序启动..............")t1 &#61; threading.Thread(target&#61;func_1, args&#61;())t2 &#61; threading.Thread(target&#61;func_2, args&#61;())t1.start()t2.start()
t1.join()t2.join()print("主程序启动..............")
主程序启动..............
func_1 starting.........
func_2 starting.........
func_2 申请了 lock_2....
func_1 申请了 lock_1....
func_1 等待 lock_2.......
func_2 等待 lock_1.......
import threading
import timelock_1 &#61; threading.Lock()
lock_2 &#61; threading.Lock()def func_1():print("func_1 starting.........")lock_1.acquire(timeout&#61;4) print("func_1 申请了 lock_1....")time.sleep(2)print("func_1 等待 lock_2.......")rst &#61; lock_2.acquire(timeout&#61;2)if rst:print("func_1 已经得到锁 lock_2")lock_2.release()print("func_1 释放了锁 lock_2")else:print("func_1 注定没申请到lock_2.....")lock_1.release()print("func_1 释放了 lock_1")print("func_1 done..........")def func_2():print("func_2 starting.........")lock_2.acquire()print("func_2 申请了 lock_2....")time.sleep(4)print("func_2 等待 lock_1.......")lock_1.acquire()print("func_2 申请了 lock_1.......")lock_1.release()print("func_2 释放了 lock_1")lock_2.release()print("func_2 释放了 lock_2")print("func_2 done..........")if __name__ &#61;&#61; "__main__":print("主程序启动..............")t1 &#61; threading.Thread(target&#61;func_1, args&#61;())t2 &#61; threading.Thread(target&#61;func_2, args&#61;())t1.start()t2.start()t1.join()t2.join()print("主程序结束..............")
import threading
import time
semaphore &#61; threading.Semaphore(3)def func():if semaphore.acquire():for i in range(5):print(threading.currentThread().getName() &#43; &#39; get semaphore&#39;)time.sleep(15)semaphore.release()print(threading.currentThread().getName() &#43; &#39; release semaphore&#39;)for i in range(8):t1 &#61; threading.Thread(target&#61;func)t1.start()
- threading.Timer
- timer是利用多线程&#xff0c;在指定时间后启动一个功能
import threading
import timedef func():print("I am running.........")time.sleep(4)print("I am done......")if __name__ &#61;&#61; "__main__":t &#61; threading.Timer(6, func)t.start()i &#61; 0while True:print("{0}***************".format(i))time.sleep(3)i &#43;&#61; 1
- 可重入锁
- 一个锁&#xff0c;可以被一个线程多次申请
- 主要解决递归调用的时候&#xff0c;需要申请锁的情况
import threading
import timeclass MyThread(threading.Thread):def run(self):global numtime.sleep(1)if mutex.acquire(1):num &#61; num&#43;1msg &#61; self.name&#43;&#39; set num to &#39;&#43;str(num)print(msg)mutex.acquire()mutex.release()mutex.release()num &#61; 0mutex &#61; threading.RLock()def testTh():for i in range(5):t &#61; MyThread()t.start()if __name__ &#61;&#61; &#39;__main__&#39;:testTh()