zoukankan      html  css  js  c++  java
  • 网络编程之线程进阶

    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('33[32m%s 拿到A锁' %self.name) mutexB.acquire() print('33[45m%s 拿到B锁' %self.name) mutexB.release() mutexA.release() def f2(self): mutexB.acquire() print('33[32m%s 拿到B锁' %self.name) time.sleep(1)#睡一秒是确保是确保有线程拿到A mutexA.acquire() print('33[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('33[32m%s 拿到A锁' %self.name)
            mutexB.acquire()
            print('33[45m%s 拿到B锁' %self.name)
            mutexB.release()
            mutexA.release()
    
        def f2(self):
            mutexB.acquire()
            print('33[32m%s 拿到B锁' %self.name)
            time.sleep(1)
            mutexA.acquire()
            print('33[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())

     

  • 相关阅读:
    MYSQL查询优化:profile功能
    MYSQL查询优化:调度和锁定
    SSL/TLS 协议详解
    flash传值给javascript,并在html页面输出
    【图片预加载】
    【minheight】最小高度 IE6、7、FF
    【图片等比缩放】CSS解决
    标签的空链接 href="#" 替换方案
    【实现三角】css的border属性解决方案
    【PNG在IE6下透明】——3种方案
  • 原文地址:https://www.cnblogs.com/1a2a/p/7454052.html
Copyright © 2011-2022 走看看