多进程_1链接:https://blog.csdn.net/weixin_42394170/article/details/95744871
- 共享变量
-
共享变量: 当多个线程同时访问一个变量的时候,会产生共享变量的问题
-
案例11
-
解决变量:锁,信号灯,
-
锁(Lock):
- 是一个标志,表示一个线程在占用一些资源
- 使用方法
- 上锁
- 使用共享资源,放心的用
- 取消锁,释放锁
- 案例12
- 锁谁: 哪个资源需要多个线程共享,锁哪个
- 理解锁:锁其实不是锁住谁,而是一个令牌
-
线程安全问题:
- 如果一个资源/变量,他对于多线程来讲,不用加锁也不会引起任何问题,则称为线程安全
- 线程不安全变量类型: list, set, dict
- 线程安全变量类型: queue
-
生产者消费者问题
- 一个模型,可以用来搭建消息队列,
- queue是一个用来存放变量的数据结构,特点是先进先出,内部元素排队,可以理解成一个特殊的list
-
死锁问题, 案例14
-
锁的等待时间问题, 案例15
-
semphore
- 允许一个资源最多由几个多线程同时使用
- 案例16
-
threading.Timer
- 案例 17
- Timer是利用多线程,在指定时间后启动一个功能
-
可重入锁
- 一个锁,可以被一个线程多次申请
- 主要解决递归调用的时候,需要申请锁的情况
- 案例18
-
**案例11**
import threading
sum = 0
loopsum = 1000000
def myAdd():
global sum,loopsum
for i in range(1,loopsum):
sum += i
def myMinu():
global sum,loopsum
for i in range(1,loopsum):
sum -= i
def main():
print("Start....{}".format(sum))
t1 = threading.Thread(target = myAdd,args=())
t2 = threading.Thread(target=myMinu,args = ())
t1.start()
t2.start()
t1.join()
t2.join()
print("End.......{}".format(sum))
if __name__ =="__main__":
main()
#运行时发现每次输出的sum都不一样
**案例12**
import threading
sum = 0
loopsum = 10000
lock = threading.Lock()
def myAdd():
global sum,loopsum
for i in range(1,loopsum):
lock.acquire()
sum+=i
lock.release()
def myMinu():
global sum,loopsum
for i in range(1,loopsum):
lock.acquire()
sum-=i
lock.release()
def main():
print("Start....{}".format(sum))
t1 = threading.Thread(target = myAdd,args= ())
t2 = threading.Thread(target = myMinu,args = ())
t1.start()
t2.start()
t1.join()
t2.join()
print("End......{}".format(sum))
if __name__ == '__main__':
main()
**案例13**
import threading
import time
import queue
class Producer(threading.Thread):
def run(self):
global q#全局变量
count = 0;
while True:
if q.qsize()<1000:
for i in range(100):
count+=1
msg = "生产产品"+str(count)
q.put(msg)
print(msg)
time.sleep(0.5)
class Consumer(threading.Thread):
def run(self):
global q#全局变量
while True:
if q.qsize()>100:
for i in range(3):
msg = self.name+"消费了"+q.get()
print(msg)
time.sleep(1)
if __name__ == '__main__':
q = queue.Queue()
for i in range(500):
q.put("初始产品" + str(i))
for i in range(2):
p = Producer()
p.start()
for i in range(3):
c = Consumer()
c.start()
**案例14**
import threading
import time
lock_1 = threading.Lock()
lock_2 = threading.Lock()
def fun1():
print("fun1 starting.....")
lock_1.acquire()
print("fun1 申请了lock_1...")
time.sleep(2)
print("fun1 等待lock_2.....")
lock_2.acquire()
print("fun1 申请了lock_2...")
lock_2.release()
print("fun1 释放了lock_2...")
lock_1.release()
print("fun1 释放了lock_1...")
def fun2():
print("fun2 starting.....")
lock_2.acquire()
print("fun2 申请了lock_2...")
time.sleep(2)
print("fun2 等待lock_1.....")
lock_1.acquire()
print("fun2 申请了lock_1...")
lock_1.release()
print("fun2 释放了lock_1...")
lock_2.release()
print("fun2 释放了lock_2...")
if __name__ == '__main__':
print("主线程启动......")
t1 = threading.Thread(target = fun1,args = ())
t2 = threading.Thread(target = fun2,args = ())
t1.start()
t2.start()
t1.join()
t2.join()
print("主线程结束.......")
**案例15**
import threading
import time
lock_1 = threading.Lock()
lock_2 = threading.Lock()
def fun1():
print("fun1 starting.....")
lock_1.acquire(timeout = 4)
print("fun1 申请了lock_1...")
time.sleep(2)
print("fun1 等待lock_2.....")
rst = lock_2.acquire(timeout = 2)
if rst:
print("fun1 申请了lock_2...")
lock_2.release()
print("fun1 释放了lock_2...")
else:
print("fun1 无法申请到lock_2...")
lock_1.release()
print("fun1 释放了lock_1...")
def fun2():
print("fun2 starting.....")
lock_2.acquire(timeout=4)
print("fun2 申请了lock_2...")
time.sleep(2)
print("fun2 等待lock_1.....")
rst = lock_1.acquire(timeout = 2)
if rst:
print("fun1 申请了lock_1...")
lock_1.release()
print("fun2 释放了lock_1...")
else:
print("fun1 无法申请到lock_1...")
lock_2.release()
print("fun2 释放了lock_2...")
if __name__ == '__main__':
print("主线程启动......")
t1 = threading.Thread(target = fun1,args = ())
t2 = threading.Thread(target = fun2,args = ())
t1.start()
t2.start()
t1.join()
t2.join()
print("主线程结束.......")
**案例16**
import threading
import time
semaphore = threading.Semaphore(3)
#以上句子表示可以三个线程同时运行
def fun():
if semaphore.acquire():
for i in range(2):
print(threading.currentThread().getName()+"get semaphore")
time.sleep(10)
semaphore.release()
print(threading.currentThread().getName()+"release semaphore")
for i in range(8):
t1 = threading.Thread(target = fun)
t1.start()
# 结果:
# Thread-1get semaphore
# Thread-1get semaphore
# Thread-2get semaphore
# Thread-2get semaphore
# Thread-3get semaphore
# Thread-3get semaphore
# Thread-1release semaphore
# Thread-4get semaphore
# Thread-4get semaphore
# Thread-2release semaphore
# Thread-5get semaphore
# Thread-5get semaphore
# Thread-3release semaphore
# Thread-6get semaphore
#
# Thread-6get semaphore
# Thread-4release semaphore
# Thread-5release semaphore
# Thread-7get semaphore
# Thread-8get semaphore
#
# Thread-7get semaphore
# Thread-8get semaphore
# Thread-6release semaphore
# Thread-8release semaphore
# Thread-7release semaphore
# 我们可以看出,首先有三个线程,之后每释放一个线程,就会添加一个新的线程
**案例17**
import threading
import time
def fun():
print("Starting .....")
time.sleep(4)
print("Ending........")
if __name__ == '__main__':
t1 = threading.Timer(5,fun)#意思是,程序运行5秒之后运行此函数
t1.start()
for i in range(5):
print("{}..........".format(i))
time.sleep(3)
# 结果:
# 0..........
# 1..........
# Starting .....
# 2..........
# Ending........
# 3..........
# 4..........
**案例18**
import threading
import time
num = 0
mutex = threading.RLock()##RLock()
class myThread(threading.Thread):
def run(self):
global num,mutex
time.sleep(1)
if mutex.acquire(1):
num+=1;
print(self.name + " set num to "+str(num))
mutex.acquire()
mutex.release()
mutex.release()
def fun():
for i in range(5):
t = myThread()
t.start()
if __name__ == '__main__':
fun()