网络编程之线程进阶

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())

 

 

posted on 2017-08-30 17:05  黎明NB  阅读(199)  评论(0编辑  收藏  举报

导航