网络编程之线程进阶
1、多线程与多进程的应用范围和join方法
2、死锁与递归锁
3、信号量
4、Event
5、定时器
6、线程Queue
1多线程与多进程的引用范围和join方法
#多线程优点是开销小缺点是不能利用多核适用于I/O操作 #多进程优点利用多核缺点开销大适用于计算操作 #window平台开进程开销大,鼓励大家多开线程,因此window平台的多线程学习重点是要大量面对资源争抢与同步方面的问题。 #linux平台开进程开销小,鼓励大家多开进程,因此linux平台的多进程学习重点是要学习进程间的通讯的方法。
#join方法可以解决竞争,保证数据安全问题。但是它把并行的程序变成了串行,影响效率。所以这个方法不可取。
''' 多进程 优点:可以利用多核 缺点:开销大 多线程 优点:开销小 缺点:不可以利用多核 ''' # #计算密集型要开启多进程 # from multiprocessing import Process # from threading import Thread # import time # def work(): # res=0 # for i in range(10000000): # res+=i # # if __name__ == '__main__': # l=[] # start=time.time() # for i in range(4): # p=Process(target=work) #3.9822275638580322运行时间 # # p=Thread(target=work) #6.686382293701172运行时间 # l.append(p) # p.start() # # for p in l: # p.join() # # stop=time.time() # print('%s' %(stop-start)) #I/O密集型要开启多线程 # from multiprocessing import Process # from threading import Thread # import time # def work(): # time.sleep(2) # # if __name__ == '__main__': # l=[] # start=time.time() # for i in range(400): # # p=Process(target=work)#42.643439292907715运行时间 # p=Thread(target=work)#2.0871193408966064运行时间 # l.append(p) # p.start() # # for p in l: # p.join() # # stop=time.time() # print('%s' %(stop-start))
2死锁与递归锁
#这种情况下回产生死锁
from threading import Lock,Thread import time mutexA=Lock() mutexB=Lock() class MyThread(Thread): def run(self): self.f1() self.f2() def f1(self): mutexA.acquire() print('\033[32m%s 拿到A锁' %self.name) mutexB.acquire() print('\033[45m%s 拿到B锁' %self.name) mutexB.release() mutexA.release() def f2(self): mutexB.acquire() print('\033[32m%s 拿到B锁' %self.name) time.sleep(1)#睡一秒是确保是确保有线程拿到A mutexA.acquire() print('\033[45m%s 拿到A锁' %self.name) mutexA.release() mutexB.release() if __name__ == '__main__': for i in range(10): t=MyThread() t.start()
#解决方案是用递归锁 from threading import Thread,RLock#递归锁 import time mutexB=mutexA=RLock() class MyThread(Thread): def run(self): self.f1() self.f2() def f1(self): mutexA.acquire() print('\033[32m%s 拿到A锁' %self.name) mutexB.acquire() print('\033[45m%s 拿到B锁' %self.name) mutexB.release() mutexA.release() def f2(self): mutexB.acquire() print('\033[32m%s 拿到B锁' %self.name) time.sleep(1) mutexA.acquire() print('\033[45m%s 拿到A锁' %self.name) mutexA.release() mutexB.release() if __name__ == '__main__': for i in range(10): t=MyThread() t.start()
3信号量
# 信号量 from threading import Thread,Semaphore,currentThread import time,random sm=Semaphore(5)#这个参数是说明正在运行的线程数 def task(): sm.acquire()#获得锁 print('%s上厕所'%currentThread().getName()) time.sleep(random.randint(1,3)) print('%s走了' % currentThread().getName()) sm.release()#释放锁 if __name__ == '__main__': for i in range(10): t=Thread(target=task) t.start()
4Event用法:
(1)红绿灯
from threading import Thread,Event,currentThread import time e=Event() def traffic_lights(): time.sleep(5)#睡了5秒 e.set()#改变event的状态的 def car(): print('%s 等'%currentThread().getName())#打印是哪个线程等待 e.wait()#等待接收状态的改变 print('%s 走' % currentThread().getName()) if __name__ == '__main__': for i in range(3):#生成3量车 t=Thread(target=car) t.start() tar=Thread(target=traffic_lights) tar.start()
(2)连接数据库
from threading import Thread,Event,currentThread import time e=Event() def check_sql(): print('%s检测sql'%currentThread().getName()) time.sleep(2) e.set() def conn_sql(): count=1 while not e.is_set(): print(e.is_set()) if count>3: raise TimeoutError('链接超时') print('%s第%s次连接'%(currentThread().getName(),count)) e.wait(timeout=1) count+=1 print('%s 开始连接' % currentThread().getName()) if __name__ == '__main__': for i in range(3): t=Thread(target=conn_sql) t.start() tar=Thread(target=check_sql()) tar.start()
5、定时器
# 定时器 # from threading import Timer # def hello(n): # print('hello',n) # t=Timer(3,hello,args=(123,))#定时为3秒钟,接着往下执行 # t.start()
6、线程Queue
#线程queue import queue # p=queue.Queue(3)#先进先出 # p.put('first') # p.put('second') # p.put('third') # print(p.get()) # print(p.get()) # print(p.get()) # p=queue.LifoQueue(3)#后进先出 # p.put('first') # p.put('second') # p.put('third') # print(p.get()) # print(p.get()) # print(p.get()) # p=queue.PriorityQueue()#根据优先级 # p.put('20,first') # p.put('30,second') # p.put('10,third') # print(p.get()) # print(p.get()) # print(p.get())
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步