多线程

多线程的开启还有其他的一些普通方法跟多进程是一样的

下面说一些不一样的

  1. 守护线程
    from threading import Thread
    import time
    '''
    守护线程跟守护进程不同的地方
    
    守护进程:当主进程后面没有代码之后,守护进程结束
    守护线程:当主进程后面没有代码并且所有线程执行结束之后,守护线程结束
    '''
    def func():
        time.sleep(2)
        print('守护线程....')
    def fun():
        time.sleep(5)
        print('普通线程...')
    if __name__ == '__main__':
        t = Thread(target=func,)
        t.daemon = True
        t.start()
        t = Thread(target=fun)
        t.start()
  2. from threading import Thread,Lock,RLock
    import time
    
    def man():
        trash.acquire()
        print('man:我拿到垃圾桶了')
        time.sleep(0.5)
        knife.acquire()
        print('man:我拿到水果刀了')
        time.sleep(1)
        knife.release()
        print('man:我削好水果了')
        trash.release()
        print('man:我还掉垃圾桶了')
    
    def woman():
        # print(666)
        knife.acquire()
        print('woman:我拿到水果刀了')
        time.sleep(0.5)
        trash.acquire()
        print('woman:我拿到垃圾桶了')
        time.sleep(1)
        trash.release()
        print('woman:我还掉垃圾桶了')
        knife.release()
        print('woman:我削好水果了')
    
    if __name__ == '__main__':
        # 死锁状态
        # knife = Lock()
        # knife = Lock()
        # RLock解决死锁状态
        # RLock可以多次acquire()的锁 几个acquire()就得有几个release()
        knife = trash = RLock()
    
    
        m_t = Thread(target=man)
        w_t = Thread(target=woman)
    
        m_t.start()
        w_t.start()
  3. 定时器
    from threading import Timer
    '''
    开线程执行
    Timer(时间(秒),要执行的函数).start()
    内部使用event的wait()
    
    
    '''
    
    def func():
        print('执行了...')
    
    if __name__ == '__main__':
        Timer(2,func).start()
  4. Condition
    from threading import Thread,Condition,RLock,Lock
    '''
    Condition 的源码解读
    1.实例化
        1.1.内部创建了一个锁 默认为RLock
        2.2.创建了一个deququ 用于存放锁
    2.con.acquire() 其实是为了锁上con.wait()内部实现的一个队列(deququ)
    
    3.con.wait()(没有加timeout的情况下)
        3.1.创建一个新锁Lock
        3.2.新锁.acquire()
        3.3.将新锁压入队列
        3.4.将实例化时创建的锁解锁
        3.5.再次新锁.acquire()实现阻塞
        3.6.等待执行notify
        3.7.阻塞解除之后 将实例化时创建的锁加锁
        3.8.执行wait后面的代码
        
        
    4.con.notify(int)
        4.1.按照传入的数字取出队列中的锁,返回一个元组
        4.2.循环元组,取出元组中的锁,然后解锁
        4.3.解锁之后,主线程解除实例化的锁
        4.3.跳转到 3.7
    
    
    '''
    
    def func(con,i):
        con.acquire()
        # print(666)
        con.wait()
        con.release()
        print('第%s个线程运行了...'%i)
    
    
    if __name__ == '__main__':
        
        con = Condition()
        # con.acquire()
        # lock = RLock()
        for i in range(10):
            t = Thread(target=func,args=(con,i,))
            t.start()
    
        while True:
    
            num = input('>>')
            con.acquire()
            con.notify(int(num))
            con.release()
  5. 进程池跟线程池的对比
    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor # 都是异步执行
    import os
    import time
    from multiprocessing import Pool
    def func(i):
        sum = 0
        for i in range(i):
            sum += i ** 2
        print(sum)
    
    
    if __name__ == '__main__':
       
        # # 线程池
        # t = ThreadPoolExecutor(os.cpu_count()*5) # 多线程开启最佳数量 cpu的核数 * 5
        # start = time.time()
        # for i in range(10000):
        #     t.submit(func,i)
        # 另一种写法
        # t.map(func,range(1000))
        # t.shutdown()  # 相当于进程Pool的 pool.close() + pool.jion() 阻塞等待线程池执行完毕
        # print('线程池执行时间:%s' % (time.time() - start)) # 23.0133159160614
    
        # 进程池
        # t = ProcessPoolExecutor(os.cpu_count() + 1)  # 多进程开启最佳数量 cpu的核数 + 1
        # start = time.time()
        # for i in range(10000):
        #     t.submit(func, i)
        # 另一种写法
        # t.map(func,range(1000))
        # t.shutdown()  # 相当于进程Pool的 pool.close() + pool.jion() 阻塞等待线程池执行完毕
        # print('进程池执行时间:%s' % (time.time() - start))  # 15.823904991149902
    
    
        # 进程池 Pool
        # t = Pool(os.cpu_count() + 1)  # 多进程开启最佳数量 cpu的核数 + 1
        # start = time.time()
        # for i in range(10000):
        #     t.apply_async(func, args=(i,))
        # t.close()
        # t.join()
        # print('进程池Pool执行时间:%s' % (time.time() - start))  # 6.565375566482544
  6. 进程池线程池的返回值
    from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
    
    
    def func(i):
        # raise ValueError
    
        return i ** i
    
    def abcd(i):
        print(i)
    
    def error(i):
        print(213)
        print(i)
    if __name__ == '__main__':
    
        t_p = ThreadPoolExecutor(40)
        # res_l = []
        # for i in range(100):
        #     res = t_p.submit(func,i)
        #     res_l.append(res)
        # t_p.shutdown()
        # res_l[0].add_done_callback(abcd) # 添加一个回调函数,回调函数至少接收一个参数,线程执行完毕之后会将自己传给回调函数
        # print(res_l[0].result())   # 取返回值
    
        # res = t_p.map(func,range(100))
        # t_p.shutdown()
        # # 取返回值
        # for i in res:
        #     print(i)
原文地址:https://www.cnblogs.com/wtil/p/11238264.html