• 线程模块threading


    线程 -Threading模块 -使用和进程基本相似

    • 多线程中是可以input

    • 在使用的过程中从用户层面上并没有感觉到和进程的差别,但是有本质差别

    • 执行代码的最小单元

    • 每一个进程至少有一个线程,这个线程是主线程

    • 一个进程内的所有线程之间的数据是共享的

        #启动多线程
        from threading import Thread
        import time
        
        def func(i):
            time.sleep(1)
            print(i)
        
        for i in range(10):
            t = Thread(target=func, args=(i,))
            t.start()
        print('这是主线程执行的')
        #结果
        这是主线程执行的
        0
        2
        1
        3
        4
        5
        9
        8
        6
        7	#这里的十个数字是几乎同时被输出,说明是个线程并发
      
    • 面向对象的形式启动线程

        #用面向对象的方法开启新的线程
        from threading import Thread
        class MyThread(Thread): #继承Thread类
            def __init__(self, arg): #重写__init__方法,用于给这个类传参
                super().__init__()  #继承父类的__init__方法
                self.arg = arg  #将自己的参数赋给对象
        
            def run(self):  		        
            '''objece.start()直接调用这个方法'''
                self.methond()
        
            def methond(self):
                '''这个类中的其他方法'''
                print(self.arg)	
      

    进程|主线程|子线程

    • 进程是最小的内存分配单位
    • 线程是操作系统调度的最小单位
    • 线程被cpu执行了
    • 进程中可以有多个线层,至少一个主线程
    • 主线程
    • 子线程
      • 子线程的数据储存在栈中
    • 全局变量global n线程共享

    线程锁 -这是解释语言的一个不可避免的问题

    • 全局解释器锁 -锁的是线程
      • 同一时刻只能有一个线程访问cpu

    进程和线程的效率对比 -线程快

    from multiprocessing import Process
    from threading import Thread
    import time
    
    def cal_num(i):
        i += 1
    
    if __name__ == '__main__':
        p_list = []
        start = time.time()
        for i in range(100):    #创建100个进程执行计算
            p = Process(target=cal_num, args=(i, ))
            p.start()
            p_list.append(p)
        for i in p_list:
            i.join()
        end = time.time()
        t1 = end - start
    
    
    start = time.time()
    t_list = []
    for i in range(100):
        t = Thread(target=cal_num, args=(i,))
        t.start()
        t_list.append(t)
    for i in t_list:
        i.join()
    end = time.time()
    t2 = end - start
    print('100个进程消耗时间{} 
     100个线程消耗时间{}'.format(t1, t2))
    #结果
    100个进程消耗时间0.19627618789672852  
    100个线程消耗时间0.009418964385986328
    

    线程中的其他方法 -threading.方法名()

    • threading.current_thread() 所有进程的情况
    • .get_ident() 查看进程的id
    • .active_count() 查看活跃进程的数量
    • .enumerate() 所有的进程情况放进一个列表中

    守护线程 -守护线程和进程的区别

    • 将子线程设置成守护线程,守护线程将在主线程代码执行结束且其他线程执行结束后结束
    • 但是守护进程是在主进程结束之后结束,不等待其他子进程是否结束

    线程锁 -Lock()和RLock

    科学家吃面模型 -死锁模型

    • Lock()的死锁现象
    • Lock()互斥锁,只有一把钥匙
    • RLock()递归锁,只要拿到一把,就等于拿到一串,必须等一串全部归还下个线程才能继续拿钥匙
      • 死锁情况

          #死锁情况
          from threading import Thread,Lock	
          from time import sleep
          #死锁情况
          from threading import Thread,Lock,RLock
          from time import sleep
          
          mt_lock = Lock()
          cz_lock = Lock()
          def miantao():
              mt_lock.acquire()
              print('拿到面条了')
              sleep(1)
              cz_lock.acquire()
              print('拿到叉子了')
              print('吃面')
              mt_lock.release()
              cz_lock.release()
          
          def chazi():
              cz_lock.acquire()
              print('拿到叉子了')
              sleep(1)
              mt_lock.acquire()
              print('拿到面条了')
              print('吃面')
              cz_lock.release()
              mt_lock.release()
          
          th1 = Thread(target=miantao, args=())
          th2 = Thread(target=chazi, args=())
          th1.start()
          th2.start()
        
      • 解决死锁问题RLock()

          from threading import Thread, Lock, RLock
          from time import sleep
          
          cz_lock = mt_lock = RLock()	#这里创建递归锁
          def miantao():
              mt_lock.acquire()
              print('拿到面条了')
              sleep(1)
              cz_lock.acquire()
              print('拿到叉子了')
              print('吃面')
              mt_lock.release()
              cz_lock.release()
          
          def chazi():
              cz_lock.acquire()
              print('拿到叉子了')
              sleep(1)
              mt_lock.acquire()
              print('拿到面条了')
              print('吃面')
              cz_lock.release()
              mt_lock.release()	
          
          th1 = Thread(target=miantao, args=())
          th2 = Thread(target=chazi, args=())
          th1.start()
          th2.start()
        

    信号量 -同进程

    • 限制一段代码有且只有n个线程同时调用

    事件 -同进程

    • 创建就为阻塞状态

    实例 -链接数据库,以及数据库的可连接的情况

    	from threading import Thread, Event
    
    	e = Event()
    	def test():
    	    '''检测数据库的连通性'''
    	    info = input('>>')
    	    if info == '1':
    	        e.set()
    	        print('数据库网络连接打开')
    	    else:
    	        print('关闭数据库网络连接')
    	def connect_q():
    	    '''连接数据库'''
    	    print('等待数据库网络连接')
    	    e.wait()
    	    print('数据库连接成功!') 	
    	
    	t1 = Thread(target=test)
    	t2 = Thread(target=connect_q)
    	t1.start()
    	t2.start() 
    

    条件 -Condition

    • .acquire() #钥匙

    • .release() #释放钥匙

    • .notify(num) #允许钥匙串有几把钥匙

    • .wait() #等待.notify(num)提供钥匙数量

        #条件
        from threading import Condition, Thread
      
        def print_thrad(con, i):
            con.acquire()	#这里也有锁
            con.wait()
            print('第{}线程运行了'.format(i)) 
            con.release()
        
        num = int(input('>>'))
        con = Condition()
        
        
        for i in range(10):
            t = Thread(target=print_thrad, args=(con, i))
            t.start()
        
        con.acquire()	#这里也有锁
        con.notify(num) #前后必须有钥匙和锁
        con.release()
      

    定时器 -Timer()

    • 定时开启一个线程

    • 用法和Threa()一致

        from threading import Timer
      
        def func():
            print('两秒时间到了')
        Timer(2, func).start()
        print('呵呵')
        #结果
        呵呵
        两秒时间到了	#子线程两秒后才开启
      

    线程队列 -queue.Queue()

    • .put() 放元素
    • .put_nowait() #放元素,没有元素报错
    • .get() #取出元素
    • .get_nowait() #没有元素报错

    其他队列模块中的类

    先进后出 LifoQueue()

    优先级队列 PriorityQueue()

  • 相关阅读:
    PKU_3624(0-1背包)
    背包问题之01背包
    背包问题
    HDU--2602(0-1背包)
    基于baseline、svd和stochastic gradient descent的个性化推荐系统
    基于baseline和stochastic gradient descent的个性化推荐系统
    基于neighborhood models(item-based) 的个性化推荐系统
    基于物品的协同过滤推荐算法——读“Item-Based Collaborative Filtering Recommendation Algorithms”
    基于用户的最近邻协同过滤算法(MovieLens数据集)
    7--操作符重载(1)
  • 原文地址:https://www.cnblogs.com/liliudong/p/9742402.html
Copyright © 2020-2023  润新知